src/js/mivhak.js   A
last analyzed

Complexity

Total Complexity 29
Complexity/F 2.07

Size

Lines of Code 193
Function Count 14

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 4
Bugs 0 Features 0
Metric Value
cc 0
c 4
b 0
f 0
nc 4
dl 0
loc 193
rs 10
wmc 29
mnd 2
bc 18
fnc 14
bpm 1.2857
cpm 2.0714
noi 14

12 Functions

Rating   Name   Duplication   Size   Complexity  
A Mivhak.methodExists 0 4 1
A Mivhak.init 0 8 1
A Mivhak.applyOptions 0 14 3
A Mivhak.parseResources 0 9 1
A Mivhak.createUI 0 10 1
A Mivhak.createCaption 0 13 3
B Mivhak.calculateHeight 0 16 7
A Mivhak.setOptions 0 9 2
A Mivhak.createLivePreview 0 8 3
A Mivhak.destroy 0 4 1
A Mivhak.initState 0 10 1
A Mivhak.callMethod 0 11 2
1
/**
2
 * The constructor.
3
 * See Mivhal.defaults for available options.
4
 * 
5
 * @param {DOMElement} selection
6
 * @param {Object} options
7
 */
8
function Mivhak( selection, options )
9
{   
10
    // Bail if there are no resources
11
    if(!selection.getElementsByTagName('PRE').length) return;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
12
    
13
    this.$selection = $( selection );
14
    this.setOptions( options );
15
    this.init();
16
}
17
18
/**
19
 * Check if a given string represents a supported method
20
 * @param {string} method
21
 */
22
Mivhak.methodExists = function( method )
23
{
24
    return typeof method === 'string' && Mivhak.methods[method];
25
};
26
27
/**
28
 * Initiate Mivhak.
29
 */
30
Mivhak.prototype.init = function() 
31
{
32
    this.initState();
33
    this.parseResources();
34
    this.createUI();
35
    this.applyOptions();
36
    this.callMethod('showTab',0); // Show first tab initially
37
};
38
39
/**
40
 * Apply the options that were set by the user. This function is called when
41
 * Mivhak is initiated, and every time the options are updated.
42
 */
43
Mivhak.prototype.applyOptions = function() 
44
{
45
    this.callMethod('setHeight', this.options.height);
46
    this.callMethod('setAccentColor', this.options.accentColor);
47
    if(this.options.collapsed) this.callMethod('collapse');
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
48
    if(!this.options.topbar) this.$selection.addClass('mivhak-no-topbar');
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
49
    else this.$selection.removeClass('mivhak-no-topbar');
50
    
51
    // If the theme option was set through jQuery, set the attribute
52
    this.$selection.attr('miv-theme',this.options.theme);
53
    
54
    this.createCaption();
55
    this.createLivePreview();
56
};
57
58
/**
59
 * Initiate this instance's state.
60
 */
61
Mivhak.prototype.initState = function() 
62
{
63
    this.state = {
64
        lineWrap:   true,
65
        collapsed:  false,
66
        height:     0,
67
        activeTab:  null,   // Updated by tabs.showTab
68
        resources:  []    // Generated by parseResources()
69
    };
70
};
71
72
/**
73
 * Set or update this instance's options.
74
 * @param {object} options
75
 */
76
Mivhak.prototype.setOptions = function( options ) 
77
{
78
    // If options were already set, update them
79
    if( typeof this.options !== 'undefined' )
80
        this.options = $.extend(true, {}, this.options, options, readAttributes(this.$selection[0]));
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
81
    
82
    // Otherwise, merge them with the defaults
83
    else this.options = $.extend(true, {}, Mivhak.defaults, options, readAttributes(this.$selection[0]));
84
};
85
86
/**
87
 * Call one of Mivhak's methods. See Mivhak.methods for available methods.
88
 * To apply additional arguments, simply pass the arguments after the methodName
89
 * i.e. callMethod('methodName', arg1, arg2).
90
 * This method is also called internally when making a method call through jQuery
91
 * i.e. $('#el').mivhak('methodName', arg1, arg2);
92
 * 
93
 * @param {string} methodName
94
 */
95
Mivhak.prototype.callMethod = function( methodName )
96
{
97
    if(Mivhak.methodExists(methodName))
98
    {
99
        // Call the method with the original arguments, removing the method's name from the list
100
        var args = [];
101
        Array.prototype.push.apply( args, arguments );
102
        args.shift();
103
        Mivhak.methods[methodName].apply(this, args);
104
    }
105
};
106
107
/**
108
 * Create the user interface.
109
 */
110
Mivhak.prototype.createUI = function() 
111
{
112
    this.tabs = Mivhak.render('tabs',{mivhakInstance: this});
113
    this.topbar = Mivhak.render('top-bar',{mivhakInstance: this});
114
    this.notifier = Mivhak.render('notifier');
115
    
116
    this.$selection.prepend(this.tabs.$el);
117
    this.$selection.prepend(this.topbar.$el);
118
    this.tabs.$el.prepend(this.notifier.$el);
119
};
120
121
/**
122
 * Calculate the height in pixels.
123
 * 
124
 * auto: Automatically calculate the height based on the number of lines.
125
 * min: Calculate the height based on the height of the tab with the maximum number of lines
126
 * max: Calculate the height based on the height of the tab with the minimum number of lines
127
 * average: Calculate the height based on the average height of all tabs
128
 * 
129
 * @param {string|number} h One of (auto|min|max|average) or a custom number
130
 * @returns {Number}
131
 */
132
Mivhak.prototype.calculateHeight = function(h)
133
{
134
    var heights = [],
135
        padding = this.options.padding*2,
136
        i = this.tabs.tabs.length;
137
138
    while(i--)
139
        heights.unshift(getEditorHeight($(this.tabs.tabs[i].resource.pre))+padding);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
140
141
    if('average' === h) return average(heights);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
142
    if('min' === h) return min(heights);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
143
    if('max' === h) return max(heights);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
144
    if('auto' === h) return getEditorHeight($(this.activeTab.resource.pre))+padding;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
145
    if(!isNaN(h)) return parseInt(h);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
146
    return heights[0];
147
};
148
149
/**
150
 * Loop through each PRE element inside this.$selection and store it's options
151
 * in this.resources, merging it with the default option values.
152
 */
153
Mivhak.prototype.parseResources = function()
154
{
155
    var $this = this;
156
    
157
    this.resources = new Resources();
0 ignored issues
show
Bug introduced by
The variable Resources seems to be never declared. If this is a global, consider adding a /** global: Resources */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
158
    this.$selection.find('pre').each(function(){
159
        $this.resources.add(this);
160
    });
161
};
162
163
Mivhak.prototype.createCaption = function()
164
{
165
    if(this.options.caption)
166
    {
167
        if(!this.caption)
168
        {
169
            this.caption = Mivhak.render('caption',{text: this.options.caption});
170
            this.$selection.append(this.caption.$el);
171
        }
172
        else this.caption.setText(this.options.caption);
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
173
    }
174
    else this.$selection.addClass('mivhak-no-caption');
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

Consider adding curly braces around all statements when they are executed conditionally. This is optional if there is only one statement, but leaving them out can lead to unexpected behaviour if another statement is added later.

Consider:

if (a > 0)
    b = 42;

If you or someone else later decides to put another statement in, only the first statement will be executed.

if (a > 0)
    console.log("a > 0");
    b = 42;

In this case the statement b = 42 will always be executed, while the logging statement will be executed conditionally.

if (a > 0) {
    console.log("a > 0");
    b = 42;
}

ensures that the proper code will be executed conditionally no matter how many statements are added or removed.

Loading history...
175
};
176
177
/**
178
 * Create the live preview iframe window
179
 */
180
Mivhak.prototype.createLivePreview = function()
181
{
182
    if(this.options.runnable && typeof this.preview === 'undefined')
183
    {
184
        this.preview = Mivhak.render('live-preview',{resources: this.resources});
185
        this.tabs.$el.append(this.preview.$el);
186
    }
187
};
188
189
/**
190
 * Remove all generated elements, data and events.
191
 * 
192
 * TODO: keep initial HTML
193
 */
194
Mivhak.prototype.destroy = function() 
195
{
196
    this.$selection.empty();
197
};
198
199
/* test-code */
200
testapi.mivhak = Mivhak;
0 ignored issues
show
Bug introduced by
The variable testapi seems to be never declared. If this is a global, consider adding a /** global: testapi */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
201
/* end-test-code */