public/lib/semantic/semantic.js   F
last analyzed

Complexity

Total Complexity 4604
Complexity/F 2.55

Size

Lines of Code 22863
Function Count 1804

Duplication

Duplicated Lines 22642
Ratio 99.03 %

Importance

Changes 0
Metric Value
cc 0
eloc 15058
nc 0
dl 22642
loc 22863
rs 0.8
c 0
b 0
f 0
wmc 4604
mnd 8
bc 4046
fnc 1804
bpm 2.2427
cpm 2.552
noi 524

177 Functions

Rating   Name   Duplication   Size   Complexity  
B $.fn.nag 419 419 2
A $.fn.accordion.settings.onChange 1 1 1
A $.fn.checkbox.settings.beforeUnchecked 1 1 1
A $.fn.dimmer.settings.onChange 1 1 1
A $.fn.checkbox.settings.onEnabled 1 1 1
A $.fn.embed.settings.onPlaceholderDisplay 1 1 1
A $.fn.checkbox.settings.onDisabled 1 1 1
A $.fn.modal.settings.onDeny 1 1 1
A $.fn.form.settings.rules.number 3 3 1
A $.fn.sticky.settings.onScroll 1 1 1
A $.fn.checkbox.settings.onChecked 1 1 1
A $.fn.dropdown.settings.onLabelRemove 1 1 1
A $.fn.form.settings.rules.empty 3 3 1
B $.fn.checkbox 752 752 2
A $.fn.search.settings.templates.escape 21 21 2
A $.fn.form.settings.rules.isExactly 3 3 1
A $.fn.dimmer.settings.onShow 1 1 1
A $.fn.modal.settings.onShow 1 1 1
A $.fn.form.settings.onFailure 1 1 1
A $.fn.embed.settings.templates.placeholder 12 12 3
C $.fn.site 411 411 6
A $.fn.form.settings.rules.is 11 11 3
A $.tab 3 3 1
A $.fn.form.settings.rules.minCount 9 9 3
A $.fn.state.settings.deactivateTest 1 1 1
A $.fn.checkbox.settings.onDisable 1 1 1
B $.fn.popup 1262 1262 2
A $.fn.dropdown.settings.templates.label 3 3 1
A $.fn.embed.settings.sources.youtube.parameters 10 10 1
A $.fn.popup.settings.onVisible 1 1 1
A $.fn.popup.settings.templates.escape 21 21 2
B $.fn.form.settings.rules.integer 30 30 7
A $.api.settings.onAbort 1 1 1
B $.fn.modal 845 845 2
A $.fn.form.settings.templates.prompt 6 6 1
A $.fn.progress.settings.onSuccess 1 1 1
B $.fn.form.settings.rules.match 22 22 6
A $.fn.dropdown.settings.onLabelSelect 1 1 1
A $.fn.modal.settings.onVisible 1 1 1
A $.fn.form.settings.templates.error 10 10 1
A $.fn.form.settings.rules.doesntContain 5 5 1
A $.api.settings.beforeXHR 1 1 1
A $.fn.visibility.settings.onLoad 1 1 1
A $.fn.progress.settings.onChange 1 1 1
A $.fn.accordion.settings.onOpen 1 1 1
A $.fn.sidebar.settings.onShow 1 1 1
B $.fn.rating 428 428 2
A $.fn.form.settings.rules.contains 5 5 1
A $.fn.search.settings.onResultsClose 1 1 1
B $.fn.api 1003 1003 3
A $.fn.embed.settings.templates.iframe 11 11 2
A $.fn.checkbox.settings.beforeChecked 1 1 1
A $.fn.form.settings.rules.regExp 21 21 5
A $.fn.form.settings.rules.containsExactly 5 5 1
B $.fn.state 573 573 2
A $.fn.sidebar.settings.onHidden 1 1 1
B $.fn.form.settings.rules.different 23 23 6
A $.fn.state.settings.onDeactivate 1 1 1
A $.fn.dropdown.settings.templates.dropdown 23 23 2
C $.fn.form.settings.rules.creditCard 106 106 9
A $.fn.modal.settings.onHidden 1 1 1
A $.fn.transition.settings.onHide 1 1 1
A $.fn.form.settings.onSuccess 1 1 1
A $.fn.nag.settings.onHide 1 1 1
A $.fn.checkbox.settings.beforeIndeterminate 1 1 1
A $.fn.shape.settings.onChange 1 1 1
A $.fn.sidebar.settings.onHide 1 1 1
A $.fn.tab.settings.onRequest 1 1 1
A $.fn.form.settings.rules.exactLength 6 6 2
A $.fn.form.settings.rules.not 11 11 3
A $.fn.sticky.settings.onReposition 1 1 1
A $.fn.dropdown.settings.templates.message 3 3 1
A $.fn.sticky.settings.onStick 1 1 1
A $.fn.search.settings.onResults 1 1 1
A $.fn.checkbox.settings.beforeDeterminate 1 1 1
A $.fn.accordion.settings.onOpening 1 1 1
A $.fn.state.settings.onActivate 1 1 1
A $.fn.form.settings.rules.notExactly 3 3 1
A $.fn.dimmer.settings.template.dimmer 3 3 1
A semantic.js ➔ ??? 4 4 1
A $.fn.popup.settings.onCreate 1 1 1
A $.fn.progress.settings.onLabelUpdate 3 3 1
A $.fn.dropdown.settings.onShow 1 1 1
B $.fn.accordion 532 532 2
A $.api.settings.onError 1 1 1
A $.fn.search.settings.onSearchQuery 1 1 1
B $.fn.search.settings.templates.category 62 62 3
A $.fn.form.settings.onValid 1 1 1
A $.fn.accordion.settings.onClosing 1 1 1
A $.fn.transition.settings.onStart 1 1 1
B $.fn.embed 544 544 2
B $.fn.transition 991 991 2
B $.fn.dimmer 615 615 2
A $.fn.tab.settings.onLoad 1 1 1
A $.fn.search.settings.onResultsOpen 1 1 1
A $.fn.form.settings.rules.exactCount 9 9 3
A $.api.settings.onSuccess 1 1 1
A $.fn.visibility.settings.onRefresh 1 1 1
A $.fn.checkbox.settings.onChange 1 1 1
A $.fn.dropdown.settings.onRemove 1 1 1
A $.fn.form.settings.rules.url 3 3 1
B $.fn.popup.settings.templates.popup 17 17 6
A $.api.settings.onFailure 1 1 1
A $.fn.checkbox.settings.onUnchecked 1 1 1
A $.fn.rating.settings.templates.icon 11 11 2
A $.fn.form.settings.rules.decimal 3 3 1
A $.fn.visibility.settings.onFixed 1 1 1
A $.fn.embed.settings.onCreate 1 1 1
A $.fn.embed.settings.onStop 1 1 1
B $.fn.shape 836 836 2
A $.fn.dropdown.settings.onChange 1 1 1
B $.fn.progress 815 815 2
A $.fn.sidebar.settings.onVisible 1 1 1
A $.fn.visibility.settings.onUnfixed 1 1 1
A $.fn.checkbox.settings.onIndeterminate 1 1 1
A $.fn.accordion.settings.onClose 1 1 1
A $.fn.dropdown.settings.onHide 1 1 1
A $.fn.transition.settings.onComplete 1 1 1
A $.fn.embed.settings.onEmbed 3 3 1
B $.fn.form 1182 1182 2
A $.fn.popup.settings.onShow 1 1 1
A $.fn.embed.settings.onDisplay 1 1 1
A $.fn.sticky.settings.onUnstick 1 1 1
A $.fn.form.settings.rules.checked 3 3 1
A $.fn.search.settings.templates.standard 47 47 3
A $.fn.embed.settings.onReset 1 1 1
A $.fn.form.settings.rules.minLength 6 6 2
A $.fn.popup.settings.onUnplaceable 1 1 1
A $.fn.popup.settings.onRemove 1 1 1
A $.fn.checkbox.settings.onEnable 1 1 1
A $.fn.popup.settings.onHidden 1 1 1
A $.fn.checkbox.settings.onDeterminate 1 1 1
A $.fn.transition.settings.onShow 1 1 1
A $.fn.embed.settings.onPause 1 1 1
A $.fn.form.settings.onInvalid 1 1 1
A $.fn.search.settings.templates.message 22 22 4
A $.fn.form.settings.rules.doesntContainExactly 5 5 1
A $.api.settings.onComplete 1 1 1
A $.fn.progress.settings.onError 1 1 1
A $.fn.popup.settings.onHide 1 1 1
A $.fn.form.settings.rules.maxLength 6 6 2
A $.api.settings.onRequest 1 1 1
A $.fn.form.settings.rules.email 3 3 1
A $.extend.easeOutQuad 3 3 1
B $.fn.visibility 1188 1188 2
B $.fn.tab 855 855 3
B $.fn.sidebar 927 927 2
A $.fn.rating.settings.onRate 1 1 1
A $.fn.shape.settings.beforeChange 1 1 1
A $.fn.embed.settings.sources.vimeo.parameters 10 10 1
A $.fn.state.settings.onChange 1 1 1
A $.fn.form.settings.rules.length 6 6 2
A $.fn.tab.settings.templates.determineTitle 1 1 1
A $.fn.dropdown.settings.onLabelCreate 1 1 1
A $.fn.tab.settings.onVisible 1 1 1
A $.fn.progress.settings.onWarning 1 1 1
A $.fn.progress.settings.onActive 1 1 1
A $.fn.dropdown.settings.templates.menu 20 20 1
A $.fn.dimmer.settings.onHide 1 1 1
A $.fn.dropdown.settings.onAdd 1 1 1
A $.fn.form.settings.rules.maxCount 9 9 3
A $.fn.modal.settings.onApprove 1 1 1
A $.fn.sticky.settings.onBottom 1 1 1
A $.fn.dropdown.settings.templates.addition 3 3 1
B $.fn.search 1140 1140 2
A $.api.settings.beforeSend 1 1 1
A $.fn.visibility.settings.onAllLoaded 1 1 1
B $.fn.dropdown 3564 3564 2
A $.fn.dropdown.settings.onNoResults 1 1 1
A $.fn.state.settings.activateTest 1 1 1
A $.fn.modal.settings.onHide 1 1 1
A $.fn.sticky.settings.onTop 1 1 1
A $.expr.createPseudo 5 5 1
A $.fn.embed.settings.onPlay 1 1 1
A $.fn.sidebar.settings.onChange 1 1 1
B $.fn.sticky 866 866 2
A $.fn.tab.settings.onFirstLoad 1 1 1

How to fix   Duplicated Code    Complexity   

Duplicated Code

Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.

Common duplication problems, and corresponding solutions are:

Complexity

 Tip:   Before tackling complexity, make sure that you eliminate any duplication first. This often can reduce the size of classes significantly.

Complex classes like public/lib/semantic/semantic.js often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

1
 /*
2
 * # Semantic UI - 2.2.11
3
 * https://github.com/Semantic-Org/Semantic-UI
4
 * http://www.semantic-ui.com/
5
 *
6
 * Copyright 2014 Contributors
7
 * Released under the MIT license
8
 * http://opensource.org/licenses/MIT
9
 *
10
 */
11
/*!
12
 * # Semantic UI 2.2.11 - Site
13
 * http://github.com/semantic-org/semantic-ui/
14
 *
15
 *
16
 * Released under the MIT license
17
 * http://opensource.org/licenses/MIT
18
 *
19
 */
20
21 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
22
23
$.site = $.fn.site = function(parameters) {
24
  var
25
    time           = new Date().getTime(),
26
    performance    = [],
27
28
    query          = arguments[0],
29
    methodInvoked  = (typeof query == 'string'),
30
    queryArguments = [].slice.call(arguments, 1),
31
32
    settings        = ( $.isPlainObject(parameters) )
33
      ? $.extend(true, {}, $.site.settings, parameters)
34
      : $.extend({}, $.site.settings),
35
36
    namespace       = settings.namespace,
37
    error           = settings.error,
38
39
    eventNamespace  = '.' + namespace,
0 ignored issues
show
Unused Code introduced by
The variable eventNamespace seems to be never used. Consider removing it.
Loading history...
40
    moduleNamespace = 'module-' + namespace,
41
42
    $document       = $(document),
43
    $module         = $document,
44
    element         = this,
45
    instance        = $module.data(moduleNamespace),
46
47
    module,
48
    returnedValue
49
  ;
50
  module = {
51
52
    initialize: function() {
53
      module.instantiate();
54
    },
55
56
    instantiate: function() {
57
      module.verbose('Storing instance of site', module);
58
      instance = module;
59
      $module
60
        .data(moduleNamespace, module)
61
      ;
62
    },
63
64
    normalize: function() {
65
      module.fix.console();
66
      module.fix.requestAnimationFrame();
67
    },
68
69
    fix: {
70
      console: function() {
71
        module.debug('Normalizing window.console');
72
        if (console === undefined || console.log === undefined) {
0 ignored issues
show
Comprehensibility Bug Compatibility introduced by
Using console === undefined to check if a variable is declared may throw an Error. Consider using typeof {name} === "undefined"instead.
Loading history...
73
          module.verbose('Console not available, normalizing events');
74
          module.disable.console();
75
        }
76
        if (typeof console.group == 'undefined' || typeof console.groupEnd == 'undefined' || typeof console.groupCollapsed == 'undefined') {
77
          module.verbose('Console group not available, normalizing events');
78
          window.console.group = function() {};
79
          window.console.groupEnd = function() {};
80
          window.console.groupCollapsed = function() {};
81
        }
82
        if (typeof console.markTimeline == 'undefined') {
83
          module.verbose('Mark timeline not available, normalizing events');
84
          window.console.markTimeline = function() {};
85
        }
86
      },
87
      consoleClear: function() {
88
        module.debug('Disabling programmatic console clearing');
89
        window.console.clear = function() {};
90
      },
91
      requestAnimationFrame: function() {
92
        module.debug('Normalizing requestAnimationFrame');
93
        if(window.requestAnimationFrame === undefined) {
94
          module.debug('RequestAnimationFrame not available, normalizing event');
95
          window.requestAnimationFrame = window.requestAnimationFrame
96
            || window.mozRequestAnimationFrame
97
            || window.webkitRequestAnimationFrame
98
            || window.msRequestAnimationFrame
99
            || function(callback) { setTimeout(callback, 0); }
100
          ;
101
        }
102
      }
103
    },
104
105
    moduleExists: function(name) {
106
      return ($.fn[name] !== undefined && $.fn[name].settings !== undefined);
107
    },
108
109
    enabled: {
110
      modules: function(modules) {
111
        var
112
          enabledModules = []
113
        ;
114
        modules = modules || settings.modules;
115
        $.each(modules, function(index, name) {
116
          if(module.moduleExists(name)) {
117
            enabledModules.push(name);
118
          }
119
        });
120
        return enabledModules;
121
      }
122
    },
123
124
    disabled: {
125
      modules: function(modules) {
126
        var
127
          disabledModules = []
128
        ;
129
        modules = modules || settings.modules;
130
        $.each(modules, function(index, name) {
131
          if(!module.moduleExists(name)) {
132
            disabledModules.push(name);
133
          }
134
        });
135
        return disabledModules;
136
      }
137
    },
138
139
    change: {
140
      setting: function(setting, value, modules, modifyExisting) {
141
        modules = (typeof modules === 'string')
142
          ? (modules === 'all')
143
            ? settings.modules
144
            : [modules]
145
          : modules || settings.modules
146
        ;
147
        modifyExisting = (modifyExisting !== undefined)
148
          ? modifyExisting
149
          : true
150
        ;
151
        $.each(modules, function(index, name) {
152
          var
153
            namespace = (module.moduleExists(name))
154
              ? $.fn[name].settings.namespace || false
155
              : true,
156
            $existingModules
157
          ;
158
          if(module.moduleExists(name)) {
159
            module.verbose('Changing default setting', setting, value, name);
160
            $.fn[name].settings[setting] = value;
161
            if(modifyExisting && namespace) {
162
              $existingModules = $(':data(module-' + namespace + ')');
163
              if($existingModules.length > 0) {
164
                module.verbose('Modifying existing settings', $existingModules);
165
                $existingModules[name]('setting', setting, value);
166
              }
167
            }
168
          }
169
        });
170
      },
171
      settings: function(newSettings, modules, modifyExisting) {
172
        modules = (typeof modules === 'string')
173
          ? [modules]
174
          : modules || settings.modules
175
        ;
176
        modifyExisting = (modifyExisting !== undefined)
177
          ? modifyExisting
178
          : true
179
        ;
180
        $.each(modules, function(index, name) {
181
          var
182
            $existingModules
183
          ;
184
          if(module.moduleExists(name)) {
185
            module.verbose('Changing default setting', newSettings, name);
186
            $.extend(true, $.fn[name].settings, newSettings);
187
            if(modifyExisting && namespace) {
188
              $existingModules = $(':data(module-' + namespace + ')');
189
              if($existingModules.length > 0) {
190
                module.verbose('Modifying existing settings', $existingModules);
191
                $existingModules[name]('setting', newSettings);
192
              }
193
            }
194
          }
195
        });
196
      }
197
    },
198
199
    enable: {
200
      console: function() {
201
        module.console(true);
202
      },
203
      debug: function(modules, modifyExisting) {
204
        modules = modules || settings.modules;
205
        module.debug('Enabling debug for modules', modules);
206
        module.change.setting('debug', true, modules, modifyExisting);
207
      },
208
      verbose: function(modules, modifyExisting) {
209
        modules = modules || settings.modules;
210
        module.debug('Enabling verbose debug for modules', modules);
211
        module.change.setting('verbose', true, modules, modifyExisting);
212
      }
213
    },
214
    disable: {
215
      console: function() {
216
        module.console(false);
217
      },
218
      debug: function(modules, modifyExisting) {
219
        modules = modules || settings.modules;
220
        module.debug('Disabling debug for modules', modules);
221
        module.change.setting('debug', false, modules, modifyExisting);
222
      },
223
      verbose: function(modules, modifyExisting) {
224
        modules = modules || settings.modules;
225
        module.debug('Disabling verbose debug for modules', modules);
226
        module.change.setting('verbose', false, modules, modifyExisting);
227
      }
228
    },
229
230
    console: function(enable) {
231
      if(enable) {
232
        if(instance.cache.console === undefined) {
233
          module.error(error.console);
234
          return;
235
        }
236
        module.debug('Restoring console function');
237
        window.console = instance.cache.console;
238
      }
239
      else {
240
        module.debug('Disabling console function');
241
        instance.cache.console = window.console;
242
        window.console = {
243
          clear          : function(){},
244
          error          : function(){},
245
          group          : function(){},
246
          groupCollapsed : function(){},
247
          groupEnd       : function(){},
248
          info           : function(){},
249
          log            : function(){},
250
          markTimeline   : function(){},
251
          warn           : function(){}
252
        };
253
      }
254
    },
255
256
    destroy: function() {
257
      module.verbose('Destroying previous site for', $module);
258
      $module
259
        .removeData(moduleNamespace)
260
      ;
261
    },
262
263
    cache: {},
264
265
    setting: function(name, value) {
266
      if( $.isPlainObject(name) ) {
267
        $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
268
      }
269
      else if(value !== undefined) {
270
        settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
271
      }
272
      else {
273
        return settings[name];
274
      }
275
    },
276
    internal: function(name, value) {
277
      if( $.isPlainObject(name) ) {
278
        $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
279
      }
280
      else if(value !== undefined) {
281
        module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
282
      }
283
      else {
284
        return module[name];
285
      }
286
    },
287
    debug: function() {
288
      if(settings.debug) {
289
        if(settings.performance) {
290
          module.performance.log(arguments);
291
        }
292
        else {
293
          module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
294
          module.debug.apply(console, arguments);
295
        }
296
      }
297
    },
298
    verbose: function() {
299
      if(settings.verbose && settings.debug) {
300
        if(settings.performance) {
301
          module.performance.log(arguments);
302
        }
303
        else {
304
          module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
305
          module.verbose.apply(console, arguments);
306
        }
307
      }
308
    },
309
    error: function() {
310
      module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
311
      module.error.apply(console, arguments);
312
    },
313
    performance: {
314
      log: function(message) {
315
        var
316
          currentTime,
317
          executionTime,
318
          previousTime
319
        ;
320
        if(settings.performance) {
321
          currentTime   = new Date().getTime();
322
          previousTime  = time || currentTime;
323
          executionTime = currentTime - previousTime;
324
          time          = currentTime;
325
          performance.push({
326
            'Element'        : element,
327
            'Name'           : message[0],
328
            'Arguments'      : [].slice.call(message, 1) || '',
329
            'Execution Time' : executionTime
330
          });
331
        }
332
        clearTimeout(module.performance.timer);
333
        module.performance.timer = setTimeout(module.performance.display, 500);
334
      },
335
      display: function() {
336
        var
337
          title = settings.name + ':',
338
          totalTime = 0
339
        ;
340
        time = false;
341
        clearTimeout(module.performance.timer);
342
        $.each(performance, function(index, data) {
343
          totalTime += data['Execution Time'];
344
        });
345
        title += ' ' + totalTime + 'ms';
346
        if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
347
          console.groupCollapsed(title);
348
          if(console.table) {
349
            console.table(performance);
350
          }
351
          else {
352
            $.each(performance, function(index, data) {
353
              console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
354
            });
355
          }
356
          console.groupEnd();
357
        }
358
        performance = [];
359
      }
360
    },
361
    invoke: function(query, passedArguments, context) {
362
      var
363
        object = instance,
364
        maxDepth,
365
        found,
366
        response
367
      ;
368
      passedArguments = passedArguments || queryArguments;
369
      context         = element         || context;
370
      if(typeof query == 'string' && object !== undefined) {
371
        query    = query.split(/[\. ]/);
372
        maxDepth = query.length - 1;
373
        $.each(query, function(depth, value) {
374
          var camelCaseValue = (depth != maxDepth)
375
            ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
376
            : query
377
          ;
378
          if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
379
            object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
380
          }
381
          else if( object[camelCaseValue] !== undefined ) {
382
            found = object[camelCaseValue];
383
            return false;
384
          }
385
          else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
386
            object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
387
          }
388
          else if( object[value] !== undefined ) {
389
            found = object[value];
390
            return false;
391
          }
392
          else {
393
            module.error(error.method, query);
394
            return false;
395
          }
396
        });
397
      }
398
      if ( $.isFunction( found ) ) {
399
        response = found.apply(context, passedArguments);
400
      }
401
      else if(found !== undefined) {
402
        response = found;
403
      }
404
      if($.isArray(returnedValue)) {
405
        returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 401 is false. Are you sure the function push handles undefined variables?
Loading history...
406
      }
407
      else if(returnedValue !== undefined) {
408
        returnedValue = [returnedValue, response];
409
      }
410
      else if(response !== undefined) {
411
        returnedValue = response;
412
      }
413
      return found;
414
    }
415
  };
416
417
  if(methodInvoked) {
418
    if(instance === undefined) {
419
      module.initialize();
420
    }
421
    module.invoke(query);
422
  }
423
  else {
424
    if(instance !== undefined) {
425
      module.destroy();
426
    }
427
    module.initialize();
428
  }
429
  return (returnedValue !== undefined)
430
    ? returnedValue
431
    : this
432
  ;
433
};
434
435
$.site.settings = {
436
437
  name        : 'Site',
438
  namespace   : 'site',
439
440
  error : {
441
    console : 'Console cannot be restored, most likely it was overwritten outside of module',
442
    method : 'The method you called is not defined.'
443
  },
444
445
  debug       : false,
446
  verbose     : false,
447
  performance : true,
448
449
  modules: [
450
    'accordion',
451
    'api',
452
    'checkbox',
453
    'dimmer',
454
    'dropdown',
455
    'embed',
456
    'form',
457
    'modal',
458
    'nag',
459
    'popup',
460
    'rating',
461
    'shape',
462
    'sidebar',
463
    'state',
464
    'sticky',
465
    'tab',
466
    'transition',
467
    'visit',
468
    'visibility'
469
  ],
470
471
  siteNamespace   : 'site',
472
  namespaceStub   : {
473
    cache     : {},
474
    config    : {},
475
    sections  : {},
476
    section   : {},
477
    utilities : {}
478
  }
479
480
};
481
482
// allows for selection of elements with data attributes
483
$.extend($.expr[ ":" ], {
484
  data: ($.expr.createPseudo)
485
    ? $.expr.createPseudo(function(dataName) {
486
        return function(elem) {
487
          return !!$.data(elem, dataName);
488
        };
489
      })
490
    : function(elem, i, match) {
491
      // support: jQuery < 1.8
492
      return !!$.data(elem, match[ 3 ]);
493
    }
494
});
495
496
497
})( jQuery, window, document );
498
499
/*!
500
 * # Semantic UI 2.2.11 - Form Validation
501
 * http://github.com/semantic-org/semantic-ui/
502
 *
503
 *
504
 * Released under the MIT license
505
 * http://opensource.org/licenses/MIT
506
 *
507
 */
508
509 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
510
511
"use strict";
512
513
window = (typeof window != 'undefined' && window.Math == Math)
0 ignored issues
show
Unused Code introduced by
The assignment to variable window seems to be never used. Consider removing it.
Loading history...
514
  ? window
515
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
516
    ? self
517
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
518
;
519
520
$.fn.form = function(parameters) {
521
  var
522
    $allModules      = $(this),
523
    moduleSelector   = $allModules.selector || '',
524
525
    time             = new Date().getTime(),
526
    performance      = [],
527
528
    query            = arguments[0],
529
    legacyParameters = arguments[1],
530
    methodInvoked    = (typeof query == 'string'),
531
    queryArguments   = [].slice.call(arguments, 1),
532
    returnedValue
533
  ;
534
  $allModules
535
    .each(function() {
536
      var
537
        $module     = $(this),
538
        element     = this,
539
540
        formErrors  = [],
541
        keyHeldDown = false,
542
543
        // set at run-time
544
        $field,
545
        $group,
546
        $message,
547
        $prompt,
548
        $submit,
549
        $clear,
550
        $reset,
551
552
        settings,
553
        validation,
554
555
        metadata,
556
        selector,
557
        className,
558
        regExp,
559
        error,
560
561
        namespace,
562
        moduleNamespace,
563
        eventNamespace,
564
565
        instance,
566
        module
567
      ;
568
569
      module      = {
570
571
        initialize: function() {
572
573
          // settings grabbed at run time
574
          module.get.settings();
575
          if(methodInvoked) {
576
            if(instance === undefined) {
577
              module.instantiate();
578
            }
579
            module.invoke(query);
580
          }
581
          else {
582
            if(instance !== undefined) {
583
              instance.invoke('destroy');
584
            }
585
            module.verbose('Initializing form validation', $module, settings);
586
            module.bindEvents();
587
            module.set.defaults();
588
            module.instantiate();
589
          }
590
        },
591
592
        instantiate: function() {
593
          module.verbose('Storing instance of module', module);
594
          instance = module;
595
          $module
596
            .data(moduleNamespace, module)
597
          ;
598
        },
599
600
        destroy: function() {
601
          module.verbose('Destroying previous module', instance);
602
          module.removeEvents();
603
          $module
604
            .removeData(moduleNamespace)
605
          ;
606
        },
607
608
        refresh: function() {
609
          module.verbose('Refreshing selector cache');
610
          $field      = $module.find(selector.field);
611
          $group      = $module.find(selector.group);
612
          $message    = $module.find(selector.message);
613
          $prompt     = $module.find(selector.prompt);
0 ignored issues
show
Unused Code introduced by
The variable $prompt seems to be never used. Consider removing it.
Loading history...
614
615
          $submit     = $module.find(selector.submit);
616
          $clear      = $module.find(selector.clear);
0 ignored issues
show
Unused Code introduced by
The variable $clear seems to be never used. Consider removing it.
Loading history...
617
          $reset      = $module.find(selector.reset);
0 ignored issues
show
Unused Code introduced by
The variable $reset seems to be never used. Consider removing it.
Loading history...
618
        },
619
620
        submit: function() {
621
          module.verbose('Submitting form', $module);
622
          $module
623
            .submit()
624
          ;
625
        },
626
627
        attachEvents: function(selector, action) {
628
          action = action || 'submit';
629
          $(selector)
630
            .on('click' + eventNamespace, function(event) {
631
              module[action]();
632
              event.preventDefault();
633
            })
634
          ;
635
        },
636
637
        bindEvents: function() {
638
          module.verbose('Attaching form events');
639
          $module
640
            .on('submit' + eventNamespace, module.validate.form)
641
            .on('blur'   + eventNamespace, selector.field, module.event.field.blur)
642
            .on('click'  + eventNamespace, selector.submit, module.submit)
643
            .on('click'  + eventNamespace, selector.reset, module.reset)
644
            .on('click'  + eventNamespace, selector.clear, module.clear)
645
          ;
646
          if(settings.keyboardShortcuts) {
647
            $module
648
              .on('keydown' + eventNamespace, selector.field, module.event.field.keydown)
649
            ;
650
          }
651
          $field
652
            .each(function() {
653
              var
654
                $input     = $(this),
655
                type       = $input.prop('type'),
656
                inputEvent = module.get.changeEvent(type, $input)
657
              ;
658
              $(this)
659
                .on(inputEvent + eventNamespace, module.event.field.change)
660
              ;
661
            })
662
          ;
663
        },
664
665
        clear: function() {
666
          $field
667
            .each(function () {
668
              var
669
                $field       = $(this),
670
                $element     = $field.parent(),
671
                $fieldGroup  = $field.closest($group),
672
                $prompt      = $fieldGroup.find(selector.prompt),
673
                defaultValue = $field.data(metadata.defaultValue) || '',
674
                isCheckbox   = $element.is(selector.uiCheckbox),
675
                isDropdown   = $element.is(selector.uiDropdown),
676
                isErrored    = $fieldGroup.hasClass(className.error)
677
              ;
678
              if(isErrored) {
679
                module.verbose('Resetting error on field', $fieldGroup);
680
                $fieldGroup.removeClass(className.error);
681
                $prompt.remove();
682
              }
683
              if(isDropdown) {
684
                module.verbose('Resetting dropdown value', $element, defaultValue);
685
                $element.dropdown('clear');
686
              }
687
              else if(isCheckbox) {
688
                $field.prop('checked', false);
689
              }
690
              else {
691
                module.verbose('Resetting field value', $field, defaultValue);
692
                $field.val('');
693
              }
694
            })
695
          ;
696
        },
697
698
        reset: function() {
699
          $field
700
            .each(function () {
701
              var
702
                $field       = $(this),
703
                $element     = $field.parent(),
704
                $fieldGroup  = $field.closest($group),
705
                $prompt      = $fieldGroup.find(selector.prompt),
706
                defaultValue = $field.data(metadata.defaultValue),
707
                isCheckbox   = $element.is(selector.uiCheckbox),
708
                isDropdown   = $element.is(selector.uiDropdown),
709
                isErrored    = $fieldGroup.hasClass(className.error)
710
              ;
711
              if(defaultValue === undefined) {
712
                return;
713
              }
714
              if(isErrored) {
715
                module.verbose('Resetting error on field', $fieldGroup);
716
                $fieldGroup.removeClass(className.error);
717
                $prompt.remove();
718
              }
719
              if(isDropdown) {
720
                module.verbose('Resetting dropdown value', $element, defaultValue);
721
                $element.dropdown('restore defaults');
722
              }
723
              else if(isCheckbox) {
724
                module.verbose('Resetting checkbox value', $element, defaultValue);
725
                $field.prop('checked', defaultValue);
726
              }
727
              else {
728
                module.verbose('Resetting field value', $field, defaultValue);
729
                $field.val(defaultValue);
730
              }
731
            })
732
          ;
733
        },
734
735
        determine: {
736
          isValid: function() {
737
            var
738
              allValid = true
739
            ;
740
            $.each(validation, function(fieldName, field) {
741
              if( !( module.validate.field(field, fieldName, true) ) ) {
742
                allValid = false;
743
              }
744
            });
745
            return allValid;
746
          }
747
        },
748
749
        is: {
750
          bracketedRule: function(rule) {
751
            return (rule.type && rule.type.match(settings.regExp.bracket));
752
          },
753
          shorthandFields: function(fields) {
754
            var
755
              fieldKeys = Object.keys(fields),
756
              firstRule = fields[fieldKeys[0]]
757
            ;
758
            return module.is.shorthandRules(firstRule);
759
          },
760
          // duck type rule test
761
          shorthandRules: function(rules) {
762
            return (typeof rules == 'string' || $.isArray(rules));
763
          },
764
          empty: function($field) {
765
            if(!$field || $field.length === 0) {
766
              return true;
767
            }
768
            else if($field.is('input[type="checkbox"]')) {
769
              return !$field.is(':checked');
770
            }
771
            else {
772
              return module.is.blank($field);
773
            }
774
          },
775
          blank: function($field) {
776
            return $.trim($field.val()) === '';
777
          },
778
          valid: function(field) {
779
            var
780
              allValid = true
781
            ;
782
            if(field) {
783
              module.verbose('Checking if field is valid', field);
784
              return module.validate.field(validation[field], field, false);
785
            }
786
            else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
787
              module.verbose('Checking if form is valid');
788
              $.each(validation, function(fieldName, field) {
0 ignored issues
show
Unused Code introduced by
The parameter field is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
789
                if( !module.is.valid(fieldName) ) {
790
                  allValid = false;
791
                }
792
              });
793
              return allValid;
794
            }
795
          }
796
        },
797
798
        removeEvents: function() {
799
          $module
800
            .off(eventNamespace)
801
          ;
802
          $field
803
            .off(eventNamespace)
804
          ;
805
          $submit
806
            .off(eventNamespace)
807
          ;
808
          $field
809
            .off(eventNamespace)
810
          ;
811
        },
812
813
        event: {
814
          field: {
815
            keydown: function(event) {
816
              var
817
                $field       = $(this),
818
                key          = event.which,
819
                isInput      = $field.is(selector.input),
820
                isCheckbox   = $field.is(selector.checkbox),
821
                isInDropdown = ($field.closest(selector.uiDropdown).length > 0),
822
                keyCode      = {
823
                  enter  : 13,
824
                  escape : 27
825
                }
826
              ;
827
              if( key == keyCode.escape) {
828
                module.verbose('Escape key pressed blurring field');
829
                $field
830
                  .blur()
831
                ;
832
              }
833
              if(!event.ctrlKey && key == keyCode.enter && isInput && !isInDropdown && !isCheckbox) {
834
                if(!keyHeldDown) {
835
                  $field
836
                    .one('keyup' + eventNamespace, module.event.field.keyup)
837
                  ;
838
                  module.submit();
839
                  module.debug('Enter pressed on input submitting form');
840
                }
841
                keyHeldDown = true;
842
              }
843
            },
844
            keyup: function() {
845
              keyHeldDown = false;
846
            },
847
            blur: function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
848
              var
849
                $field          = $(this),
850
                $fieldGroup     = $field.closest($group),
851
                validationRules = module.get.validation($field)
852
              ;
853
              if( $fieldGroup.hasClass(className.error) ) {
854
                module.debug('Revalidating field', $field, validationRules);
855
                if(validationRules) {
856
                  module.validate.field( validationRules );
857
                }
858
              }
859
              else if(settings.on == 'blur' || settings.on == 'change') {
860
                if(validationRules) {
861
                  module.validate.field( validationRules );
862
                }
863
              }
864
            },
865
            change: function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
866
              var
867
                $field      = $(this),
868
                $fieldGroup = $field.closest($group),
869
                validationRules = module.get.validation($field)
870
              ;
871
              if(validationRules && (settings.on == 'change' || ( $fieldGroup.hasClass(className.error) && settings.revalidate) )) {
872
                clearTimeout(module.timer);
873
                module.timer = setTimeout(function() {
874
                  module.debug('Revalidating field', $field,  module.get.validation($field));
875
                  module.validate.field( validationRules );
876
                }, settings.delay);
877
              }
878
            }
879
          }
880
881
        },
882
883
        get: {
884
          ancillaryValue: function(rule) {
885
            if(!rule.type || (!rule.value && !module.is.bracketedRule(rule))) {
886
              return false;
887
            }
888
            return (rule.value !== undefined)
889
              ? rule.value
890
              : rule.type.match(settings.regExp.bracket)[1] + ''
891
            ;
892
          },
893
          ruleName: function(rule) {
894
            if( module.is.bracketedRule(rule) ) {
895
              return rule.type.replace(rule.type.match(settings.regExp.bracket)[0], '');
896
            }
897
            return rule.type;
898
          },
899
          changeEvent: function(type, $input) {
900
            if(type == 'checkbox' || type == 'radio' || type == 'hidden' || $input.is('select')) {
901
              return 'change';
902
            }
903
            else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
904
              return module.get.inputEvent();
905
            }
906
          },
907
          inputEvent: function() {
908
            return (document.createElement('input').oninput !== undefined)
909
              ? 'input'
910
              : (document.createElement('input').onpropertychange !== undefined)
911
                ? 'propertychange'
912
                : 'keyup'
913
            ;
914
          },
915
          fieldsFromShorthand: function(fields) {
916
            var
917
              fullFields = {}
918
            ;
919
            $.each(fields, function(name, rules) {
920
              if(typeof rules == 'string') {
921
                rules = [rules];
922
              }
923
              fullFields[name] = {
924
                rules: []
925
              };
926
              $.each(rules, function(index, rule) {
927
                fullFields[name].rules.push({ type: rule });
928
              });
929
            });
930
            return fullFields;
931
          },
932
          prompt: function(rule, field) {
933
            var
934
              ruleName      = module.get.ruleName(rule),
935
              ancillary     = module.get.ancillaryValue(rule),
936
              prompt        = rule.prompt || settings.prompt[ruleName] || settings.text.unspecifiedRule,
937
              requiresValue = (prompt.search('{value}') !== -1),
938
              requiresName  = (prompt.search('{name}') !== -1),
939
              $label,
940
              $field,
941
              name
942
            ;
943
            if(requiresName || requiresValue) {
944
              $field = module.get.field(field.identifier);
945
            }
946
            if(requiresValue) {
947
              prompt = prompt.replace('{value}', $field.val());
0 ignored issues
show
Bug introduced by
The variable $field does not seem to be initialized in case requiresName || requiresValue on line 943 is false. Are you sure this can never be the case?
Loading history...
948
            }
949
            if(requiresName) {
950
              $label = $field.closest(selector.group).find('label').eq(0);
951
              name = ($label.length == 1)
0 ignored issues
show
Best Practice introduced by
Comparing $label.length to 1 using the == operator is not safe. Consider using === instead.
Loading history...
952
                ? $label.text()
953
                : $field.prop('placeholder') || settings.text.unspecifiedField
954
              ;
955
              prompt = prompt.replace('{name}', name);
956
            }
957
            prompt = prompt.replace('{identifier}', field.identifier);
958
            prompt = prompt.replace('{ruleValue}', ancillary);
959
            if(!rule.prompt) {
960
              module.verbose('Using default validation prompt for type', prompt, ruleName);
961
            }
962
            return prompt;
963
          },
964
          settings: function() {
965
            if($.isPlainObject(parameters)) {
966
              var
967
                keys     = Object.keys(parameters),
968
                isLegacySettings = (keys.length > 0)
969
                  ? (parameters[keys[0]].identifier !== undefined && parameters[keys[0]].rules !== undefined)
970
                  : false,
971
                ruleKeys
0 ignored issues
show
Unused Code introduced by
The variable ruleKeys seems to be never used. Consider removing it.
Loading history...
972
              ;
973
              if(isLegacySettings) {
974
                // 1.x (ducktyped)
975
                settings   = $.extend(true, {}, $.fn.form.settings, legacyParameters);
976
                validation = $.extend({}, $.fn.form.settings.defaults, parameters);
977
                module.error(settings.error.oldSyntax, element);
978
                module.verbose('Extending settings from legacy parameters', validation, settings);
979
              }
980
              else {
981
                // 2.x
982
                if(parameters.fields && module.is.shorthandFields(parameters.fields)) {
983
                  parameters.fields = module.get.fieldsFromShorthand(parameters.fields);
984
                }
985
                settings   = $.extend(true, {}, $.fn.form.settings, parameters);
986
                validation = $.extend({}, $.fn.form.settings.defaults, settings.fields);
987
                module.verbose('Extending settings', validation, settings);
988
              }
989
            }
990
            else {
991
              settings   = $.fn.form.settings;
992
              validation = $.fn.form.settings.defaults;
993
              module.verbose('Using default form validation', validation, settings);
994
            }
995
996
            // shorthand
997
            namespace       = settings.namespace;
998
            metadata        = settings.metadata;
999
            selector        = settings.selector;
1000
            className       = settings.className;
1001
            regExp          = settings.regExp;
1002
            error           = settings.error;
1003
            moduleNamespace = 'module-' + namespace;
1004
            eventNamespace  = '.' + namespace;
1005
1006
            // grab instance
1007
            instance = $module.data(moduleNamespace);
1008
1009
            // refresh selector cache
1010
            module.refresh();
1011
          },
1012
          field: function(identifier) {
1013
            module.verbose('Finding field with identifier', identifier);
1014
            identifier = module.escape.string(identifier);
1015
            if($field.filter('#' + identifier).length > 0 ) {
1016
              return $field.filter('#' + identifier);
1017
            }
1018
            else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
1019
              return $field.filter('[name="' + identifier +'"]');
1020
            }
1021
            else if( $field.filter('[name="' + identifier +'[]"]').length > 0 ) {
1022
              return $field.filter('[name="' + identifier +'[]"]');
1023
            }
1024
            else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
1025
              return $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]');
1026
            }
1027
            return $('<input/>');
1028
          },
1029
          fields: function(fields) {
1030
            var
1031
              $fields = $()
1032
            ;
1033
            $.each(fields, function(index, name) {
1034
              $fields = $fields.add( module.get.field(name) );
1035
            });
1036
            return $fields;
1037
          },
1038
          validation: function($field) {
1039
            var
1040
              fieldValidation,
1041
              identifier
1042
            ;
1043
            if(!validation) {
1044
              return false;
1045
            }
1046
            $.each(validation, function(fieldName, field) {
1047
              identifier = field.identifier || fieldName;
1048
              if( module.get.field(identifier)[0] == $field[0] ) {
1049
                field.identifier = identifier;
1050
                fieldValidation = field;
1051
              }
1052
            });
1053
            return fieldValidation || false;
1054
          },
1055
          value: function (field) {
1056
            var
1057
              fields = [],
1058
              results
1059
            ;
1060
            fields.push(field);
1061
            results = module.get.values.call(element, fields);
1062
            return results[field];
1063
          },
1064
          values: function (fields) {
1065
            var
1066
              $fields = $.isArray(fields)
1067
                ? module.get.fields(fields)
1068
                : $field,
1069
              values = {}
1070
            ;
1071
            $fields.each(function(index, field) {
1072
              var
1073
                $field     = $(field),
1074
                type       = $field.prop('type'),
0 ignored issues
show
Unused Code introduced by
The variable type seems to be never used. Consider removing it.
Loading history...
1075
                name       = $field.prop('name'),
1076
                value      = $field.val(),
1077
                isCheckbox = $field.is(selector.checkbox),
1078
                isRadio    = $field.is(selector.radio),
1079
                isMultiple = (name.indexOf('[]') !== -1),
1080
                isChecked  = (isCheckbox)
1081
                  ? $field.is(':checked')
1082
                  : false
1083
              ;
1084
              if(name) {
1085
                if(isMultiple) {
1086
                  name = name.replace('[]', '');
1087
                  if(!values[name]) {
1088
                    values[name] = [];
1089
                  }
1090
                  if(isCheckbox) {
1091
                    if(isChecked) {
1092
                      values[name].push(value || true);
1093
                    }
1094
                    else {
1095
                      values[name].push(false);
1096
                    }
1097
                  }
1098
                  else {
1099
                    values[name].push(value);
1100
                  }
1101
                }
1102
                else {
1103
                  if(isRadio) {
1104
                    if(values[name] === undefined) {
1105
                      values[name] = (isChecked)
1106
                        ? true
1107
                        : false
1108
                      ;
1109
                    }
1110
                  }
1111
                  else if(isCheckbox) {
1112
                    if(isChecked) {
1113
                      values[name] = value || true;
1114
                    }
1115
                    else {
1116
                      values[name] = false;
1117
                    }
1118
                  }
1119
                  else {
1120
                    values[name] = value;
1121
                  }
1122
                }
1123
              }
1124
            });
1125
            return values;
1126
          }
1127
        },
1128
1129
        has: {
1130
1131
          field: function(identifier) {
1132
            module.verbose('Checking for existence of a field with identifier', identifier);
1133
            identifier = module.escape.string(identifier);
1134
            if(typeof identifier !== 'string') {
1135
              module.error(error.identifier, identifier);
1136
            }
1137
            if($field.filter('#' + identifier).length > 0 ) {
1138
              return true;
1139
            }
1140
            else if( $field.filter('[name="' + identifier +'"]').length > 0 ) {
1141
              return true;
1142
            }
1143
            else if( $field.filter('[data-' + metadata.validate + '="'+ identifier +'"]').length > 0 ) {
1144
              return true;
1145
            }
1146
            return false;
1147
          }
1148
1149
        },
1150
1151
        escape: {
1152
          string: function(text) {
1153
            text =  String(text);
1154
            return text.replace(regExp.escape, '\\$&');
1155
          }
1156
        },
1157
1158
        add: {
1159
          // alias
1160
          rule: function(name, rules) {
1161
            module.add.field(name, rules);
1162
          },
1163
          field: function(name, rules) {
1164
            var
1165
              newValidation = {}
1166
            ;
1167
            if(module.is.shorthandRules(rules)) {
1168
              rules = $.isArray(rules)
1169
                ? rules
1170
                : [rules]
1171
              ;
1172
              newValidation[name] = {
1173
                rules: []
1174
              };
1175
              $.each(rules, function(index, rule) {
1176
                newValidation[name].rules.push({ type: rule });
1177
              });
1178
            }
1179
            else {
1180
              newValidation[name] = rules;
1181
            }
1182
            validation = $.extend({}, validation, newValidation);
1183
            module.debug('Adding rules', newValidation, validation);
1184
          },
1185
          fields: function(fields) {
1186
            var
1187
              newValidation
1188
            ;
1189
            if(fields && module.is.shorthandFields(fields)) {
1190
              newValidation = module.get.fieldsFromShorthand(fields);
1191
            }
1192
            else {
1193
              newValidation = fields;
1194
            }
1195
            validation = $.extend({}, validation, newValidation);
1196
          },
1197
          prompt: function(identifier, errors) {
1198
            var
1199
              $field       = module.get.field(identifier),
1200
              $fieldGroup  = $field.closest($group),
1201
              $prompt      = $fieldGroup.children(selector.prompt),
1202
              promptExists = ($prompt.length !== 0)
1203
            ;
1204
            errors = (typeof errors == 'string')
1205
              ? [errors]
1206
              : errors
1207
            ;
1208
            module.verbose('Adding field error state', identifier);
1209
            $fieldGroup
1210
              .addClass(className.error)
1211
            ;
1212
            if(settings.inline) {
1213
              if(!promptExists) {
1214
                $prompt = settings.templates.prompt(errors);
1215
                $prompt
1216
                  .appendTo($fieldGroup)
1217
                ;
1218
              }
1219
              $prompt
1220
                .html(errors[0])
1221
              ;
1222
              if(!promptExists) {
1223
                if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
1224
                  module.verbose('Displaying error with css transition', settings.transition);
1225
                  $prompt.transition(settings.transition + ' in', settings.duration);
1226
                }
1227
                else {
1228
                  module.verbose('Displaying error with fallback javascript animation');
1229
                  $prompt
1230
                    .fadeIn(settings.duration)
1231
                  ;
1232
                }
1233
              }
1234
              else {
1235
                module.verbose('Inline errors are disabled, no inline error added', identifier);
1236
              }
1237
            }
1238
          },
1239
          errors: function(errors) {
1240
            module.debug('Adding form error messages', errors);
1241
            module.set.error();
1242
            $message
1243
              .html( settings.templates.error(errors) )
1244
            ;
1245
          }
1246
        },
1247
1248
        remove: {
1249
          rule: function(field, rule) {
1250
            var
1251
              rules = $.isArray(rule)
1252
                ? rule
1253
                : [rule]
1254
            ;
1255
            if(rule == undefined) {
0 ignored issues
show
Best Practice introduced by
Comparing rule to undefined using the == operator is not safe. Consider using === instead.
Loading history...
1256
              module.debug('Removed all rules');
1257
              validation[field].rules = [];
1258
              return;
1259
            }
1260
            if(validation[field] == undefined || !$.isArray(validation[field].rules)) {
0 ignored issues
show
Best Practice introduced by
Comparing validation.field to undefined using the == operator is not safe. Consider using === instead.
Loading history...
1261
              return;
1262
            }
1263
            $.each(validation[field].rules, function(index, rule) {
1264
              if(rules.indexOf(rule.type) !== -1) {
1265
                module.debug('Removed rule', rule.type);
1266
                validation[field].rules.splice(index, 1);
1267
              }
1268
            });
1269
          },
1270
          field: function(field) {
1271
            var
1272
              fields = $.isArray(field)
1273
                ? field
1274
                : [field]
1275
            ;
1276
            $.each(fields, function(index, field) {
1277
              module.remove.rule(field);
1278
            });
1279
          },
1280
          // alias
1281
          rules: function(field, rules) {
1282
            if($.isArray(field)) {
1283
              $.each(fields, function(index, field) {
0 ignored issues
show
Bug introduced by
The variable fields seems to be never declared. If this is a global, consider adding a /** global: fields */ 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...
1284
                module.remove.rule(field, rules);
1285
              });
1286
            }
1287
            else {
1288
              module.remove.rule(field, rules);
1289
            }
1290
          },
1291
          fields: function(fields) {
1292
            module.remove.field(fields);
1293
          },
1294
          prompt: function(identifier) {
1295
            var
1296
              $field      = module.get.field(identifier),
1297
              $fieldGroup = $field.closest($group),
1298
              $prompt     = $fieldGroup.children(selector.prompt)
1299
            ;
1300
            $fieldGroup
1301
              .removeClass(className.error)
1302
            ;
1303
            if(settings.inline && $prompt.is(':visible')) {
1304
              module.verbose('Removing prompt for field', identifier);
1305
              if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
1306
                $prompt.transition(settings.transition + ' out', settings.duration, function() {
1307
                  $prompt.remove();
1308
                });
1309
              }
1310
              else {
1311
                $prompt
1312
                  .fadeOut(settings.duration, function(){
1313
                    $prompt.remove();
1314
                  })
1315
                ;
1316
              }
1317
            }
1318
          }
1319
        },
1320
1321
        set: {
1322
          success: function() {
1323
            $module
1324
              .removeClass(className.error)
1325
              .addClass(className.success)
1326
            ;
1327
          },
1328
          defaults: function () {
1329
            $field
1330
              .each(function () {
1331
                var
1332
                  $field     = $(this),
1333
                  isCheckbox = ($field.filter(selector.checkbox).length > 0),
1334
                  value      = (isCheckbox)
1335
                    ? $field.is(':checked')
1336
                    : $field.val()
1337
                ;
1338
                $field.data(metadata.defaultValue, value);
1339
              })
1340
            ;
1341
          },
1342
          error: function() {
1343
            $module
1344
              .removeClass(className.success)
1345
              .addClass(className.error)
1346
            ;
1347
          },
1348
          value: function (field, value) {
1349
            var
1350
              fields = {}
1351
            ;
1352
            fields[field] = value;
1353
            return module.set.values.call(element, fields);
1354
          },
1355
          values: function (fields) {
1356
            if($.isEmptyObject(fields)) {
1357
              return;
1358
            }
1359
            $.each(fields, function(key, value) {
1360
              var
1361
                $field      = module.get.field(key),
1362
                $element    = $field.parent(),
1363
                isMultiple  = $.isArray(value),
1364
                isCheckbox  = $element.is(selector.uiCheckbox),
1365
                isDropdown  = $element.is(selector.uiDropdown),
1366
                isRadio     = ($field.is(selector.radio) && isCheckbox),
1367
                fieldExists = ($field.length > 0),
1368
                $multipleField
1369
              ;
1370
              if(fieldExists) {
1371
                if(isMultiple && isCheckbox) {
1372
                  module.verbose('Selecting multiple', value, $field);
1373
                  $element.checkbox('uncheck');
1374
                  $.each(value, function(index, value) {
1375
                    $multipleField = $field.filter('[value="' + value + '"]');
1376
                    $element       = $multipleField.parent();
1377
                    if($multipleField.length > 0) {
1378
                      $element.checkbox('check');
1379
                    }
1380
                  });
1381
                }
1382
                else if(isRadio) {
1383
                  module.verbose('Selecting radio value', value, $field);
1384
                  $field.filter('[value="' + value + '"]')
1385
                    .parent(selector.uiCheckbox)
1386
                      .checkbox('check')
1387
                  ;
1388
                }
1389
                else if(isCheckbox) {
1390
                  module.verbose('Setting checkbox value', value, $element);
1391
                  if(value === true) {
1392
                    $element.checkbox('check');
1393
                  }
1394
                  else {
1395
                    $element.checkbox('uncheck');
1396
                  }
1397
                }
1398
                else if(isDropdown) {
1399
                  module.verbose('Setting dropdown value', value, $element);
1400
                  $element.dropdown('set selected', value);
1401
                }
1402
                else {
1403
                  module.verbose('Setting field value', value, $field);
1404
                  $field.val(value);
1405
                }
1406
              }
1407
            });
1408
          }
1409
        },
1410
1411
        validate: {
1412
1413
          form: function(event, ignoreCallbacks) {
1414
            var
1415
              values = module.get.values(),
1416
              apiRequest
0 ignored issues
show
Unused Code introduced by
The variable apiRequest seems to be never used. Consider removing it.
Loading history...
1417
            ;
1418
1419
            // input keydown event will fire submit repeatedly by browser default
1420
            if(keyHeldDown) {
1421
              return false;
1422
            }
1423
1424
            // reset errors
1425
            formErrors = [];
1426
            if( module.determine.isValid() ) {
1427
              module.debug('Form has no validation errors, submitting');
1428
              module.set.success();
1429
              if(ignoreCallbacks !== true) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if ignoreCallbacks !== true is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
1430
                return settings.onSuccess.call(element, event, values);
1431
              }
1432
            }
1433
            else {
1434
              module.debug('Form has errors');
1435
              module.set.error();
1436
              if(!settings.inline) {
1437
                module.add.errors(formErrors);
1438
              }
1439
              // prevent ajax submit
1440
              if($module.data('moduleApi') !== undefined) {
1441
                event.stopImmediatePropagation();
1442
              }
1443
              if(ignoreCallbacks !== true) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if ignoreCallbacks !== true is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
1444
                return settings.onFailure.call(element, formErrors, values);
1445
              }
1446
            }
1447
          },
1448
1449
          // takes a validation object and returns whether field passes validation
1450
          field: function(field, fieldName, showErrors) {
1451
            showErrors = (showErrors !== undefined)
1452
              ? showErrors
1453
              : true
1454
            ;
1455
            if(typeof field == 'string') {
1456
              module.verbose('Validating field', field);
1457
              fieldName = field;
1458
              field     = validation[field];
1459
            }
1460
            var
1461
              identifier    = field.identifier || fieldName,
1462
              $field        = module.get.field(identifier),
1463
              $dependsField = (field.depends)
1464
                ? module.get.field(field.depends)
1465
                : false,
1466
              fieldValid  = true,
1467
              fieldErrors = []
1468
            ;
1469
            if(!field.identifier) {
1470
              module.debug('Using field name as identifier', identifier);
1471
              field.identifier = identifier;
1472
            }
1473
            if($field.prop('disabled')) {
1474
              module.debug('Field is disabled. Skipping', identifier);
1475
              fieldValid = true;
1476
            }
1477
            else if(field.optional && module.is.blank($field)){
1478
              module.debug('Field is optional and blank. Skipping', identifier);
1479
              fieldValid = true;
1480
            }
1481
            else if(field.depends && module.is.empty($dependsField)) {
1482
              module.debug('Field depends on another value that is not present or empty. Skipping', $dependsField);
1483
              fieldValid = true;
1484
            }
1485
            else if(field.rules !== undefined) {
1486
              $.each(field.rules, function(index, rule) {
1487
                if( module.has.field(identifier) && !( module.validate.rule(field, rule) ) ) {
1488
                  module.debug('Field is invalid', identifier, rule.type);
1489
                  fieldErrors.push(module.get.prompt(rule, field));
1490
                  fieldValid = false;
1491
                }
1492
              });
1493
            }
1494
            if(fieldValid) {
1495
              if(showErrors) {
1496
                module.remove.prompt(identifier, fieldErrors);
1497
                settings.onValid.call($field);
1498
              }
1499
            }
1500
            else {
1501
              if(showErrors) {
1502
                formErrors = formErrors.concat(fieldErrors);
1503
                module.add.prompt(identifier, fieldErrors);
1504
                settings.onInvalid.call($field, fieldErrors);
1505
              }
1506
              return false;
1507
            }
1508
            return true;
1509
          },
1510
1511
          // takes validation rule and returns whether field passes rule
1512
          rule: function(field, rule) {
1513
            var
1514
              $field       = module.get.field(field.identifier),
1515
              type         = rule.type,
0 ignored issues
show
Unused Code introduced by
The assignment to variable type seems to be never used. Consider removing it.
Loading history...
1516
              value        = $field.val(),
1517
              isValid      = true,
0 ignored issues
show
Unused Code introduced by
The variable isValid seems to be never used. Consider removing it.
Loading history...
1518
              ancillary    = module.get.ancillaryValue(rule),
1519
              ruleName     = module.get.ruleName(rule),
1520
              ruleFunction = settings.rules[ruleName]
1521
            ;
1522
            if( !$.isFunction(ruleFunction) ) {
1523
              module.error(error.noRule, ruleName);
1524
              return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
1525
            }
1526
            // cast to string avoiding encoding special values
1527
            value = (value === undefined || value === '' || value === null)
1528
              ? ''
1529
              : $.trim(value + '')
1530
            ;
1531
            return ruleFunction.call($field, value, ancillary);
1532
          }
1533
        },
1534
1535
        setting: function(name, value) {
1536
          if( $.isPlainObject(name) ) {
1537
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
1538
          }
1539
          else if(value !== undefined) {
1540
            settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
1541
          }
1542
          else {
1543
            return settings[name];
1544
          }
1545
        },
1546
        internal: function(name, value) {
1547
          if( $.isPlainObject(name) ) {
1548
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
1549
          }
1550
          else if(value !== undefined) {
1551
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
1552
          }
1553
          else {
1554
            return module[name];
1555
          }
1556
        },
1557
        debug: function() {
1558
          if(!settings.silent && settings.debug) {
1559
            if(settings.performance) {
1560
              module.performance.log(arguments);
1561
            }
1562
            else {
1563
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
1564
              module.debug.apply(console, arguments);
1565
            }
1566
          }
1567
        },
1568
        verbose: function() {
1569
          if(!settings.silent && settings.verbose && settings.debug) {
1570
            if(settings.performance) {
1571
              module.performance.log(arguments);
1572
            }
1573
            else {
1574
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
1575
              module.verbose.apply(console, arguments);
1576
            }
1577
          }
1578
        },
1579
        error: function() {
1580
          if(!settings.silent) {
1581
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
1582
            module.error.apply(console, arguments);
1583
          }
1584
        },
1585
        performance: {
1586
          log: function(message) {
1587
            var
1588
              currentTime,
1589
              executionTime,
1590
              previousTime
1591
            ;
1592
            if(settings.performance) {
1593
              currentTime   = new Date().getTime();
1594
              previousTime  = time || currentTime;
1595
              executionTime = currentTime - previousTime;
1596
              time          = currentTime;
1597
              performance.push({
1598
                'Name'           : message[0],
1599
                'Arguments'      : [].slice.call(message, 1) || '',
1600
                'Element'        : element,
1601
                'Execution Time' : executionTime
1602
              });
1603
            }
1604
            clearTimeout(module.performance.timer);
1605
            module.performance.timer = setTimeout(module.performance.display, 500);
1606
          },
1607
          display: function() {
1608
            var
1609
              title = settings.name + ':',
1610
              totalTime = 0
1611
            ;
1612
            time = false;
1613
            clearTimeout(module.performance.timer);
1614
            $.each(performance, function(index, data) {
1615
              totalTime += data['Execution Time'];
1616
            });
1617
            title += ' ' + totalTime + 'ms';
1618
            if(moduleSelector) {
1619
              title += ' \'' + moduleSelector + '\'';
1620
            }
1621
            if($allModules.length > 1) {
1622
              title += ' ' + '(' + $allModules.length + ')';
1623
            }
1624
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
1625
              console.groupCollapsed(title);
1626
              if(console.table) {
1627
                console.table(performance);
1628
              }
1629
              else {
1630
                $.each(performance, function(index, data) {
1631
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
1632
                });
1633
              }
1634
              console.groupEnd();
1635
            }
1636
            performance = [];
1637
          }
1638
        },
1639
        invoke: function(query, passedArguments, context) {
1640
          var
1641
            object = instance,
1642
            maxDepth,
1643
            found,
1644
            response
1645
          ;
1646
          passedArguments = passedArguments || queryArguments;
1647
          context         = element         || context;
1648
          if(typeof query == 'string' && object !== undefined) {
1649
            query    = query.split(/[\. ]/);
1650
            maxDepth = query.length - 1;
1651
            $.each(query, function(depth, value) {
1652
              var camelCaseValue = (depth != maxDepth)
1653
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
1654
                : query
1655
              ;
1656
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
1657
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
1658
              }
1659
              else if( object[camelCaseValue] !== undefined ) {
1660
                found = object[camelCaseValue];
1661
                return false;
1662
              }
1663
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
1664
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
1665
              }
1666
              else if( object[value] !== undefined ) {
1667
                found = object[value];
1668
                return false;
1669
              }
1670
              else {
1671
                return false;
1672
              }
1673
            });
1674
          }
1675
          if( $.isFunction( found ) ) {
1676
            response = found.apply(context, passedArguments);
1677
          }
1678
          else if(found !== undefined) {
1679
            response = found;
1680
          }
1681
          if($.isArray(returnedValue)) {
1682
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 1678 is false. Are you sure the function push handles undefined variables?
Loading history...
1683
          }
1684
          else if(returnedValue !== undefined) {
1685
            returnedValue = [returnedValue, response];
1686
          }
1687
          else if(response !== undefined) {
1688
            returnedValue = response;
1689
          }
1690
          return found;
1691
        }
1692
      };
1693
      module.initialize();
1694
    })
1695
  ;
1696
1697
  return (returnedValue !== undefined)
1698
    ? returnedValue
1699
    : this
1700
  ;
1701
};
1702
1703
$.fn.form.settings = {
1704
1705
  name              : 'Form',
1706
  namespace         : 'form',
1707
1708
  debug             : false,
1709
  verbose           : false,
1710
  performance       : true,
1711
1712
  fields            : false,
1713
1714
  keyboardShortcuts : true,
1715
  on                : 'submit',
1716
  inline            : false,
1717
1718
  delay             : 200,
1719
  revalidate        : true,
1720
1721
  transition        : 'scale',
1722
  duration          : 200,
1723
1724
  onValid           : function() {},
1725
  onInvalid         : function() {},
1726
  onSuccess         : function() { return true; },
1727
  onFailure         : function() { return false; },
1728
1729
  metadata : {
1730
    defaultValue : 'default',
1731
    validate     : 'validate'
1732
  },
1733
1734
  regExp: {
1735
    htmlID  : /^[a-zA-Z][\w:.-]*$/g,
1736
    bracket : /\[(.*)\]/i,
1737
    decimal : /^\d+\.?\d*$/,
1738
    email   : /^[a-z0-9!#$%&'*+\/=?^_`{|}~.-]+@[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,
1739
    escape  : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
1740
    flags   : /^\/(.*)\/(.*)?/,
1741
    integer : /^\-?\d+$/,
1742
    number  : /^\-?\d*(\.\d+)?$/,
1743
    url     : /(https?:\/\/(?:www\.|(?!www))[^\s\.]+\.[^\s]{2,}|www\.[^\s]+\.[^\s]{2,})/i
1744
  },
1745
1746
  text: {
1747
    unspecifiedRule  : 'Please enter a valid value',
1748
    unspecifiedField : 'This field'
1749
  },
1750
1751
  prompt: {
1752
    empty                : '{name} must have a value',
1753
    checked              : '{name} must be checked',
1754
    email                : '{name} must be a valid e-mail',
1755
    url                  : '{name} must be a valid url',
1756
    regExp               : '{name} is not formatted correctly',
1757
    integer              : '{name} must be an integer',
1758
    decimal              : '{name} must be a decimal number',
1759
    number               : '{name} must be set to a number',
1760
    is                   : '{name} must be "{ruleValue}"',
1761
    isExactly            : '{name} must be exactly "{ruleValue}"',
1762
    not                  : '{name} cannot be set to "{ruleValue}"',
1763
    notExactly           : '{name} cannot be set to exactly "{ruleValue}"',
1764
    contain              : '{name} cannot contain "{ruleValue}"',
1765
    containExactly       : '{name} cannot contain exactly "{ruleValue}"',
1766
    doesntContain        : '{name} must contain  "{ruleValue}"',
1767
    doesntContainExactly : '{name} must contain exactly "{ruleValue}"',
1768
    minLength            : '{name} must be at least {ruleValue} characters',
1769
    length               : '{name} must be at least {ruleValue} characters',
1770
    exactLength          : '{name} must be exactly {ruleValue} characters',
1771
    maxLength            : '{name} cannot be longer than {ruleValue} characters',
1772
    match                : '{name} must match {ruleValue} field',
1773
    different            : '{name} must have a different value than {ruleValue} field',
1774
    creditCard           : '{name} must be a valid credit card number',
1775
    minCount             : '{name} must have at least {ruleValue} choices',
1776
    exactCount           : '{name} must have exactly {ruleValue} choices',
1777
    maxCount             : '{name} must have {ruleValue} or less choices'
1778
  },
1779
1780
  selector : {
1781
    checkbox   : 'input[type="checkbox"], input[type="radio"]',
1782
    clear      : '.clear',
1783
    field      : 'input, textarea, select',
1784
    group      : '.field',
1785
    input      : 'input',
1786
    message    : '.error.message',
1787
    prompt     : '.prompt.label',
1788
    radio      : 'input[type="radio"]',
1789
    reset      : '.reset:not([type="reset"])',
1790
    submit     : '.submit:not([type="submit"])',
1791
    uiCheckbox : '.ui.checkbox',
1792
    uiDropdown : '.ui.dropdown'
1793
  },
1794
1795
  className : {
1796
    error   : 'error',
1797
    label   : 'ui prompt label',
1798
    pressed : 'down',
1799
    success : 'success'
1800
  },
1801
1802
  error: {
1803
    identifier : 'You must specify a string identifier for each field',
1804
    method     : 'The method you called is not defined.',
1805
    noRule     : 'There is no rule matching the one you specified',
1806
    oldSyntax  : 'Starting in 2.0 forms now only take a single settings object. Validation settings converted to new syntax automatically.'
1807
  },
1808
1809
  templates: {
1810
1811
    // template that produces error message
1812
    error: function(errors) {
1813
      var
1814
        html = '<ul class="list">'
1815
      ;
1816
      $.each(errors, function(index, value) {
1817
        html += '<li>' + value + '</li>';
1818
      });
1819
      html += '</ul>';
1820
      return $(html);
1821
    },
1822
1823
    // template that produces label
1824
    prompt: function(errors) {
1825
      return $('<div/>')
1826
        .addClass('ui basic red pointing prompt label')
1827
        .html(errors[0])
1828
      ;
1829
    }
1830
  },
1831
1832
  rules: {
1833
1834
    // is not empty or blank string
1835
    empty: function(value) {
1836
      return !(value === undefined || '' === value || $.isArray(value) && value.length === 0);
1837
    },
1838
1839
    // checkbox checked
1840
    checked: function() {
1841
      return ($(this).filter(':checked').length > 0);
1842
    },
1843
1844
    // is most likely an email
1845
    email: function(value){
1846
      return $.fn.form.settings.regExp.email.test(value);
1847
    },
1848
1849
    // value is most likely url
1850
    url: function(value) {
1851
      return $.fn.form.settings.regExp.url.test(value);
1852
    },
1853
1854
    // matches specified regExp
1855
    regExp: function(value, regExp) {
1856
      if(regExp instanceof RegExp) {
1857
        return value.match(regExp);
1858
      }
1859
      var
1860
        regExpParts = regExp.match($.fn.form.settings.regExp.flags),
1861
        flags
1862
      ;
1863
      // regular expression specified as /baz/gi (flags)
1864
      if(regExpParts) {
1865
        regExp = (regExpParts.length >= 2)
1866
          ? regExpParts[1]
1867
          : regExp
1868
        ;
1869
        flags = (regExpParts.length >= 3)
1870
          ? regExpParts[2]
1871
          : ''
1872
        ;
1873
      }
1874
      return value.match( new RegExp(regExp, flags) );
0 ignored issues
show
Bug introduced by
The variable flags does not seem to be initialized in case regExpParts on line 1864 is false. Are you sure this can never be the case?
Loading history...
1875
    },
1876
1877
    // is valid integer or matches range
1878
    integer: function(value, range) {
1879
      var
1880
        intRegExp = $.fn.form.settings.regExp.integer,
1881
        min,
1882
        max,
1883
        parts
1884
      ;
1885
      if( !range || ['', '..'].indexOf(range) !== -1) {
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
1886
        // do nothing
1887
      }
1888
      else if(range.indexOf('..') == -1) {
1889
        if(intRegExp.test(range)) {
1890
          min = max = range - 0;
1891
        }
1892
      }
1893
      else {
1894
        parts = range.split('..', 2);
1895
        if(intRegExp.test(parts[0])) {
1896
          min = parts[0] - 0;
1897
        }
1898
        if(intRegExp.test(parts[1])) {
1899
          max = parts[1] - 0;
1900
        }
1901
      }
1902
      return (
1903
        intRegExp.test(value) &&
1904
        (min === undefined || value >= min) &&
0 ignored issues
show
Bug introduced by
The variable min seems to not be initialized for all possible execution paths.
Loading history...
1905
        (max === undefined || value <= max)
0 ignored issues
show
Bug introduced by
The variable max seems to not be initialized for all possible execution paths.
Loading history...
1906
      );
1907
    },
1908
1909
    // is valid number (with decimal)
1910
    decimal: function(value) {
1911
      return $.fn.form.settings.regExp.decimal.test(value);
1912
    },
1913
1914
    // is valid number
1915
    number: function(value) {
1916
      return $.fn.form.settings.regExp.number.test(value);
1917
    },
1918
1919
    // is value (case insensitive)
1920
    is: function(value, text) {
1921
      text = (typeof text == 'string')
1922
        ? text.toLowerCase()
1923
        : text
1924
      ;
1925
      value = (typeof value == 'string')
1926
        ? value.toLowerCase()
1927
        : value
1928
      ;
1929
      return (value == text);
1930
    },
1931
1932
    // is value
1933
    isExactly: function(value, text) {
1934
      return (value == text);
1935
    },
1936
1937
    // value is not another value (case insensitive)
1938
    not: function(value, notValue) {
1939
      value = (typeof value == 'string')
1940
        ? value.toLowerCase()
1941
        : value
1942
      ;
1943
      notValue = (typeof notValue == 'string')
1944
        ? notValue.toLowerCase()
1945
        : notValue
1946
      ;
1947
      return (value != notValue);
1948
    },
1949
1950
    // value is not another value (case sensitive)
1951
    notExactly: function(value, notValue) {
1952
      return (value != notValue);
1953
    },
1954
1955
    // value contains text (insensitive)
1956
    contains: function(value, text) {
1957
      // escape regex characters
1958
      text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1959
      return (value.search( new RegExp(text, 'i') ) !== -1);
1960
    },
1961
1962
    // value contains text (case sensitive)
1963
    containsExactly: function(value, text) {
1964
      // escape regex characters
1965
      text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1966
      return (value.search( new RegExp(text) ) !== -1);
1967
    },
1968
1969
    // value contains text (insensitive)
1970
    doesntContain: function(value, text) {
1971
      // escape regex characters
1972
      text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1973
      return (value.search( new RegExp(text, 'i') ) === -1);
1974
    },
1975
1976
    // value contains text (case sensitive)
1977
    doesntContainExactly: function(value, text) {
1978
      // escape regex characters
1979
      text = text.replace($.fn.form.settings.regExp.escape, "\\$&");
1980
      return (value.search( new RegExp(text) ) === -1);
1981
    },
1982
1983
    // is at least string length
1984
    minLength: function(value, requiredLength) {
1985
      return (value !== undefined)
1986
        ? (value.length >= requiredLength)
1987
        : false
1988
      ;
1989
    },
1990
1991
    // see rls notes for 2.0.6 (this is a duplicate of minLength)
1992
    length: function(value, requiredLength) {
1993
      return (value !== undefined)
1994
        ? (value.length >= requiredLength)
1995
        : false
1996
      ;
1997
    },
1998
1999
    // is exactly length
2000
    exactLength: function(value, requiredLength) {
2001
      return (value !== undefined)
2002
        ? (value.length == requiredLength)
2003
        : false
2004
      ;
2005
    },
2006
2007
    // is less than length
2008
    maxLength: function(value, maxLength) {
2009
      return (value !== undefined)
2010
        ? (value.length <= maxLength)
2011
        : false
2012
      ;
2013
    },
2014
2015
    // matches another field
2016
    match: function(value, identifier) {
2017
      var
2018
        $form = $(this),
0 ignored issues
show
Unused Code introduced by
The variable $form seems to be never used. Consider removing it.
Loading history...
2019
        matchingValue
2020
      ;
2021
      if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
2022
        matchingValue = $('[data-validate="'+ identifier +'"]').val();
2023
      }
2024
      else if($('#' + identifier).length > 0) {
2025
        matchingValue = $('#' + identifier).val();
2026
      }
2027
      else if($('[name="' + identifier +'"]').length > 0) {
2028
        matchingValue = $('[name="' + identifier + '"]').val();
2029
      }
2030
      else if( $('[name="' + identifier +'[]"]').length > 0 ) {
2031
        matchingValue = $('[name="' + identifier +'[]"]');
2032
      }
2033
      return (matchingValue !== undefined)
0 ignored issues
show
Bug introduced by
The variable matchingValue does not seem to be initialized in case $("[name="" + identifier + "[]"]").length > 0 on line 2030 is false. Are you sure this can never be the case?
Loading history...
2034
        ? ( value.toString() == matchingValue.toString() )
2035
        : false
2036
      ;
2037
    },
2038
2039
    // different than another field
2040
    different: function(value, identifier) {
2041
      // use either id or name of field
2042
      var
2043
        $form = $(this),
0 ignored issues
show
Unused Code introduced by
The variable $form seems to be never used. Consider removing it.
Loading history...
2044
        matchingValue
2045
      ;
2046
      if( $('[data-validate="'+ identifier +'"]').length > 0 ) {
2047
        matchingValue = $('[data-validate="'+ identifier +'"]').val();
2048
      }
2049
      else if($('#' + identifier).length > 0) {
2050
        matchingValue = $('#' + identifier).val();
2051
      }
2052
      else if($('[name="' + identifier +'"]').length > 0) {
2053
        matchingValue = $('[name="' + identifier + '"]').val();
2054
      }
2055
      else if( $('[name="' + identifier +'[]"]').length > 0 ) {
2056
        matchingValue = $('[name="' + identifier +'[]"]');
2057
      }
2058
      return (matchingValue !== undefined)
0 ignored issues
show
Bug introduced by
The variable matchingValue does not seem to be initialized in case $("[name="" + identifier + "[]"]").length > 0 on line 2055 is false. Are you sure this can never be the case?
Loading history...
2059
        ? ( value.toString() !== matchingValue.toString() )
2060
        : false
2061
      ;
2062
    },
2063
2064
    creditCard: function(cardNumber, cardTypes) {
2065
      var
2066
        cards = {
2067
          visa: {
2068
            pattern : /^4/,
2069
            length  : [16]
2070
          },
2071
          amex: {
2072
            pattern : /^3[47]/,
2073
            length  : [15]
2074
          },
2075
          mastercard: {
2076
            pattern : /^5[1-5]/,
2077
            length  : [16]
2078
          },
2079
          discover: {
2080
            pattern : /^(6011|622(12[6-9]|1[3-9][0-9]|[2-8][0-9]{2}|9[0-1][0-9]|92[0-5]|64[4-9])|65)/,
2081
            length  : [16]
2082
          },
2083
          unionPay: {
2084
            pattern : /^(62|88)/,
2085
            length  : [16, 17, 18, 19]
2086
          },
2087
          jcb: {
2088
            pattern : /^35(2[89]|[3-8][0-9])/,
2089
            length  : [16]
2090
          },
2091
          maestro: {
2092
            pattern : /^(5018|5020|5038|6304|6759|676[1-3])/,
2093
            length  : [12, 13, 14, 15, 16, 17, 18, 19]
2094
          },
2095
          dinersClub: {
2096
            pattern : /^(30[0-5]|^36)/,
2097
            length  : [14]
2098
          },
2099
          laser: {
2100
            pattern : /^(6304|670[69]|6771)/,
2101
            length  : [16, 17, 18, 19]
2102
          },
2103
          visaElectron: {
2104
            pattern : /^(4026|417500|4508|4844|491(3|7))/,
2105
            length  : [16]
2106
          }
2107
        },
2108
        valid         = {},
0 ignored issues
show
Unused Code introduced by
The assignment to variable valid seems to be never used. Consider removing it.
Loading history...
2109
        validCard     = false,
2110
        requiredTypes = (typeof cardTypes == 'string')
2111
          ? cardTypes.split(',')
2112
          : false,
2113
        unionPay,
2114
        validation
2115
      ;
2116
2117
      if(typeof cardNumber !== 'string' || cardNumber.length === 0) {
2118
        return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
2119
      }
2120
2121
      // allow dashes in card
2122
      cardNumber = cardNumber.replace(/[\-]/g, '');
2123
2124
      // verify card types
2125
      if(requiredTypes) {
2126
        $.each(requiredTypes, function(index, type){
2127
          // verify each card type
2128
          validation = cards[type];
2129
          if(validation) {
2130
            valid = {
2131
              length  : ($.inArray(cardNumber.length, validation.length) !== -1),
2132
              pattern : (cardNumber.search(validation.pattern) !== -1)
2133
            };
2134
            if(valid.length && valid.pattern) {
2135
              validCard = true;
2136
            }
2137
          }
2138
        });
2139
2140
        if(!validCard) {
2141
          return false;
2142
        }
2143
      }
2144
2145
      // skip luhn for UnionPay
2146
      unionPay = {
2147
        number  : ($.inArray(cardNumber.length, cards.unionPay.length) !== -1),
2148
        pattern : (cardNumber.search(cards.unionPay.pattern) !== -1)
2149
      };
2150
      if(unionPay.number && unionPay.pattern) {
2151
        return true;
2152
      }
2153
2154
      // verify luhn, adapted from  <https://gist.github.com/2134376>
2155
      var
2156
        length        = cardNumber.length,
2157
        multiple      = 0,
2158
        producedValue = [
2159
          [0, 1, 2, 3, 4, 5, 6, 7, 8, 9],
2160
          [0, 2, 4, 6, 8, 1, 3, 5, 7, 9]
2161
        ],
2162
        sum           = 0
2163
      ;
2164
      while (length--) {
2165
        sum += producedValue[multiple][parseInt(cardNumber.charAt(length), 10)];
2166
        multiple ^= 1;
2167
      }
2168
      return (sum % 10 === 0 && sum > 0);
2169
    },
2170
2171
    minCount: function(value, minCount) {
2172
      if(minCount == 0) {
0 ignored issues
show
Best Practice introduced by
Comparing minCount to 0 using the == operator is not safe. Consider using === instead.
Loading history...
2173
        return true;
2174
      }
2175
      if(minCount == 1) {
2176
        return (value !== '');
2177
      }
2178
      return (value.split(',').length >= minCount);
2179
    },
2180
2181
    exactCount: function(value, exactCount) {
2182
      if(exactCount == 0) {
0 ignored issues
show
Best Practice introduced by
Comparing exactCount to 0 using the == operator is not safe. Consider using === instead.
Loading history...
2183
        return (value === '');
2184
      }
2185
      if(exactCount == 1) {
2186
        return (value !== '' && value.search(',') === -1);
2187
      }
2188
      return (value.split(',').length == exactCount);
2189
    },
2190
2191
    maxCount: function(value, maxCount) {
2192
      if(maxCount == 0) {
0 ignored issues
show
Best Practice introduced by
Comparing maxCount to 0 using the == operator is not safe. Consider using === instead.
Loading history...
2193
        return false;
2194
      }
2195
      if(maxCount == 1) {
2196
        return (value.search(',') === -1);
2197
      }
2198
      return (value.split(',').length <= maxCount);
2199
    }
2200
  }
2201
2202
};
2203
2204
})( jQuery, window, document );
2205
2206
/*!
2207
 * # Semantic UI 2.2.11 - Accordion
2208
 * http://github.com/semantic-org/semantic-ui/
2209
 *
2210
 *
2211
 * Released under the MIT license
2212
 * http://opensource.org/licenses/MIT
2213
 *
2214
 */
2215
2216 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2217
2218
"use strict";
2219
2220
window = (typeof window != 'undefined' && window.Math == Math)
2221
  ? window
2222
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
2223
    ? self
2224
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
2225
;
2226
2227
$.fn.accordion = function(parameters) {
2228
  var
2229
    $allModules     = $(this),
2230
2231
    time            = new Date().getTime(),
2232
    performance     = [],
2233
2234
    query           = arguments[0],
2235
    methodInvoked   = (typeof query == 'string'),
2236
    queryArguments  = [].slice.call(arguments, 1),
2237
2238
    requestAnimationFrame = window.requestAnimationFrame
0 ignored issues
show
Unused Code introduced by
The assignment to variable requestAnimationFrame seems to be never used. Consider removing it.
Loading history...
2239
      || window.mozRequestAnimationFrame
2240
      || window.webkitRequestAnimationFrame
2241
      || window.msRequestAnimationFrame
2242
      || function(callback) { setTimeout(callback, 0); },
2243
2244
    returnedValue
2245
  ;
2246
  $allModules
2247
    .each(function() {
2248
      var
2249
        settings        = ( $.isPlainObject(parameters) )
2250
          ? $.extend(true, {}, $.fn.accordion.settings, parameters)
2251
          : $.extend({}, $.fn.accordion.settings),
2252
2253
        className       = settings.className,
2254
        namespace       = settings.namespace,
2255
        selector        = settings.selector,
2256
        error           = settings.error,
2257
2258
        eventNamespace  = '.' + namespace,
2259
        moduleNamespace = 'module-' + namespace,
2260
        moduleSelector  = $allModules.selector || '',
2261
2262
        $module  = $(this),
2263
        $title   = $module.find(selector.title),
2264
        $content = $module.find(selector.content),
2265
2266
        element  = this,
2267
        instance = $module.data(moduleNamespace),
2268
        observer,
2269
        module
2270
      ;
2271
2272
      module = {
2273
2274
        initialize: function() {
2275
          module.debug('Initializing', $module);
2276
          module.bind.events();
2277
          if(settings.observeChanges) {
2278
            module.observeChanges();
2279
          }
2280
          module.instantiate();
2281
        },
2282
2283
        instantiate: function() {
2284
          instance = module;
2285
          $module
2286
            .data(moduleNamespace, module)
2287
          ;
2288
        },
2289
2290
        destroy: function() {
2291
          module.debug('Destroying previous instance', $module);
2292
          $module
2293
            .off(eventNamespace)
2294
            .removeData(moduleNamespace)
2295
          ;
2296
        },
2297
2298
        refresh: function() {
2299
          $title   = $module.find(selector.title);
2300
          $content = $module.find(selector.content);
2301
        },
2302
2303
        observeChanges: function() {
2304
          if('MutationObserver' in window) {
2305
            observer = new MutationObserver(function(mutations) {
0 ignored issues
show
Unused Code introduced by
The parameter mutations is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Bug introduced by
The variable MutationObserver seems to be never declared. If this is a global, consider adding a /** global: MutationObserver */ 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...
2306
              module.debug('DOM tree modified, updating selector cache');
2307
              module.refresh();
2308
            });
2309
            observer.observe(element, {
2310
              childList : true,
2311
              subtree   : true
2312
            });
2313
            module.debug('Setting up mutation observer', observer);
2314
          }
2315
        },
2316
2317
        bind: {
2318
          events: function() {
2319
            module.debug('Binding delegated events');
2320
            $module
2321
              .on(settings.on + eventNamespace, selector.trigger, module.event.click)
2322
            ;
2323
          }
2324
        },
2325
2326
        event: {
2327
          click: function() {
2328
            module.toggle.call(this);
2329
          }
2330
        },
2331
2332
        toggle: function(query) {
2333
          var
2334
            $activeTitle = (query !== undefined)
2335
              ? (typeof query === 'number')
2336
                ? $title.eq(query)
2337
                : $(query).closest(selector.title)
2338
              : $(this).closest(selector.title),
2339
            $activeContent = $activeTitle.next($content),
2340
            isAnimating = $activeContent.hasClass(className.animating),
2341
            isActive    = $activeContent.hasClass(className.active),
2342
            isOpen      = (isActive && !isAnimating),
2343
            isOpening   = (!isActive && isAnimating)
2344
          ;
2345
          module.debug('Toggling visibility of content', $activeTitle);
2346
          if(isOpen || isOpening) {
2347
            if(settings.collapsible) {
2348
              module.close.call($activeTitle);
2349
            }
2350
            else {
2351
              module.debug('Cannot close accordion content collapsing is disabled');
2352
            }
2353
          }
2354
          else {
2355
            module.open.call($activeTitle);
2356
          }
2357
        },
2358
2359
        open: function(query) {
2360
          var
2361
            $activeTitle = (query !== undefined)
2362
              ? (typeof query === 'number')
2363
                ? $title.eq(query)
2364
                : $(query).closest(selector.title)
2365
              : $(this).closest(selector.title),
2366
            $activeContent = $activeTitle.next($content),
2367
            isAnimating = $activeContent.hasClass(className.animating),
2368
            isActive    = $activeContent.hasClass(className.active),
2369
            isOpen      = (isActive || isAnimating)
2370
          ;
2371
          if(isOpen) {
2372
            module.debug('Accordion already open, skipping', $activeContent);
2373
            return;
2374
          }
2375
          module.debug('Opening accordion content', $activeTitle);
2376
          settings.onOpening.call($activeContent);
2377
          if(settings.exclusive) {
2378
            module.closeOthers.call($activeTitle);
2379
          }
2380
          $activeTitle
2381
            .addClass(className.active)
2382
          ;
2383
          $activeContent
2384
            .stop(true, true)
2385
            .addClass(className.animating)
2386
          ;
2387
          if(settings.animateChildren) {
2388
            if($.fn.transition !== undefined && $module.transition('is supported')) {
2389
              $activeContent
2390
                .children()
2391
                  .transition({
2392
                    animation   : 'fade in',
2393
                    queue       : false,
2394
                    useFailSafe : true,
2395
                    debug       : settings.debug,
2396
                    verbose     : settings.verbose,
2397
                    duration    : settings.duration
2398
                  })
2399
              ;
2400
            }
2401
            else {
2402
              $activeContent
2403
                .children()
2404
                  .stop(true, true)
2405
                  .animate({
2406
                    opacity: 1
2407
                  }, settings.duration, module.resetOpacity)
2408
              ;
2409
            }
2410
          }
2411
          $activeContent
2412
            .slideDown(settings.duration, settings.easing, function() {
2413
              $activeContent
2414
                .removeClass(className.animating)
2415
                .addClass(className.active)
2416
              ;
2417
              module.reset.display.call(this);
2418
              settings.onOpen.call(this);
2419
              settings.onChange.call(this);
2420
            })
2421
          ;
2422
        },
2423
2424
        close: function(query) {
2425
          var
2426
            $activeTitle = (query !== undefined)
2427
              ? (typeof query === 'number')
2428
                ? $title.eq(query)
2429
                : $(query).closest(selector.title)
2430
              : $(this).closest(selector.title),
2431
            $activeContent = $activeTitle.next($content),
2432
            isAnimating    = $activeContent.hasClass(className.animating),
2433
            isActive       = $activeContent.hasClass(className.active),
2434
            isOpening      = (!isActive && isAnimating),
2435
            isClosing      = (isActive && isAnimating)
2436
          ;
2437
          if((isActive || isOpening) && !isClosing) {
2438
            module.debug('Closing accordion content', $activeContent);
2439
            settings.onClosing.call($activeContent);
2440
            $activeTitle
2441
              .removeClass(className.active)
2442
            ;
2443
            $activeContent
2444
              .stop(true, true)
2445
              .addClass(className.animating)
2446
            ;
2447
            if(settings.animateChildren) {
2448
              if($.fn.transition !== undefined && $module.transition('is supported')) {
2449
                $activeContent
2450
                  .children()
2451
                    .transition({
2452
                      animation   : 'fade out',
2453
                      queue       : false,
2454
                      useFailSafe : true,
2455
                      debug       : settings.debug,
2456
                      verbose     : settings.verbose,
2457
                      duration    : settings.duration
2458
                    })
2459
                ;
2460
              }
2461
              else {
2462
                $activeContent
2463
                  .children()
2464
                    .stop(true, true)
2465
                    .animate({
2466
                      opacity: 0
2467
                    }, settings.duration, module.resetOpacity)
2468
                ;
2469
              }
2470
            }
2471
            $activeContent
2472
              .slideUp(settings.duration, settings.easing, function() {
2473
                $activeContent
2474
                  .removeClass(className.animating)
2475
                  .removeClass(className.active)
2476
                ;
2477
                module.reset.display.call(this);
2478
                settings.onClose.call(this);
2479
                settings.onChange.call(this);
2480
              })
2481
            ;
2482
          }
2483
        },
2484
2485
        closeOthers: function(index) {
2486
          var
2487
            $activeTitle = (index !== undefined)
2488
              ? $title.eq(index)
2489
              : $(this).closest(selector.title),
2490
            $parentTitles    = $activeTitle.parents(selector.content).prev(selector.title),
2491
            $activeAccordion = $activeTitle.closest(selector.accordion),
2492
            activeSelector   = selector.title + '.' + className.active + ':visible',
2493
            activeContent    = selector.content + '.' + className.active + ':visible',
2494
            $openTitles,
2495
            $nestedTitles,
2496
            $openContents
2497
          ;
2498
          if(settings.closeNested) {
2499
            $openTitles   = $activeAccordion.find(activeSelector).not($parentTitles);
2500
            $openContents = $openTitles.next($content);
2501
          }
2502
          else {
2503
            $openTitles   = $activeAccordion.find(activeSelector).not($parentTitles);
2504
            $nestedTitles = $activeAccordion.find(activeContent).find(activeSelector).not($parentTitles);
2505
            $openTitles   = $openTitles.not($nestedTitles);
2506
            $openContents = $openTitles.next($content);
2507
          }
2508
          if( ($openTitles.length > 0) ) {
2509
            module.debug('Exclusive enabled, closing other content', $openTitles);
2510
            $openTitles
2511
              .removeClass(className.active)
2512
            ;
2513
            $openContents
2514
              .removeClass(className.animating)
2515
              .stop(true, true)
2516
            ;
2517
            if(settings.animateChildren) {
2518
              if($.fn.transition !== undefined && $module.transition('is supported')) {
2519
                $openContents
2520
                  .children()
2521
                    .transition({
2522
                      animation   : 'fade out',
2523
                      useFailSafe : true,
2524
                      debug       : settings.debug,
2525
                      verbose     : settings.verbose,
2526
                      duration    : settings.duration
2527
                    })
2528
                ;
2529
              }
2530
              else {
2531
                $openContents
2532
                  .children()
2533
                    .stop(true, true)
2534
                    .animate({
2535
                      opacity: 0
2536
                    }, settings.duration, module.resetOpacity)
2537
                ;
2538
              }
2539
            }
2540
            $openContents
2541
              .slideUp(settings.duration , settings.easing, function() {
2542
                $(this).removeClass(className.active);
2543
                module.reset.display.call(this);
2544
              })
2545
            ;
2546
          }
2547
        },
2548
2549
        reset: {
2550
2551
          display: function() {
2552
            module.verbose('Removing inline display from element', this);
2553
            $(this).css('display', '');
2554
            if( $(this).attr('style') === '') {
2555
              $(this)
2556
                .attr('style', '')
2557
                .removeAttr('style')
2558
              ;
2559
            }
2560
          },
2561
2562
          opacity: function() {
2563
            module.verbose('Removing inline opacity from element', this);
2564
            $(this).css('opacity', '');
2565
            if( $(this).attr('style') === '') {
2566
              $(this)
2567
                .attr('style', '')
2568
                .removeAttr('style')
2569
              ;
2570
            }
2571
          },
2572
2573
        },
2574
2575
        setting: function(name, value) {
2576
          module.debug('Changing setting', name, value);
2577
          if( $.isPlainObject(name) ) {
2578
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
2579
          }
2580
          else if(value !== undefined) {
2581
            if($.isPlainObject(settings[name])) {
2582
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
2583
            }
2584
            else {
2585
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
2586
            }
2587
          }
2588
          else {
2589
            return settings[name];
2590
          }
2591
        },
2592
        internal: function(name, value) {
2593
          module.debug('Changing internal', name, value);
2594
          if(value !== undefined) {
2595
            if( $.isPlainObject(name) ) {
2596
              $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
2597
            }
2598
            else {
2599
              module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
2600
            }
2601
          }
2602
          else {
2603
            return module[name];
2604
          }
2605
        },
2606
        debug: function() {
2607
          if(!settings.silent && settings.debug) {
2608
            if(settings.performance) {
2609
              module.performance.log(arguments);
2610
            }
2611
            else {
2612
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
2613
              module.debug.apply(console, arguments);
2614
            }
2615
          }
2616
        },
2617
        verbose: function() {
2618
          if(!settings.silent && settings.verbose && settings.debug) {
2619
            if(settings.performance) {
2620
              module.performance.log(arguments);
2621
            }
2622
            else {
2623
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
2624
              module.verbose.apply(console, arguments);
2625
            }
2626
          }
2627
        },
2628
        error: function() {
2629
          if(!settings.silent) {
2630
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
2631
            module.error.apply(console, arguments);
2632
          }
2633
        },
2634
        performance: {
2635
          log: function(message) {
2636
            var
2637
              currentTime,
2638
              executionTime,
2639
              previousTime
2640
            ;
2641
            if(settings.performance) {
2642
              currentTime   = new Date().getTime();
2643
              previousTime  = time || currentTime;
2644
              executionTime = currentTime - previousTime;
2645
              time          = currentTime;
2646
              performance.push({
2647
                'Name'           : message[0],
2648
                'Arguments'      : [].slice.call(message, 1) || '',
2649
                'Element'        : element,
2650
                'Execution Time' : executionTime
2651
              });
2652
            }
2653
            clearTimeout(module.performance.timer);
2654
            module.performance.timer = setTimeout(module.performance.display, 500);
2655
          },
2656
          display: function() {
2657
            var
2658
              title = settings.name + ':',
2659
              totalTime = 0
2660
            ;
2661
            time = false;
2662
            clearTimeout(module.performance.timer);
2663
            $.each(performance, function(index, data) {
2664
              totalTime += data['Execution Time'];
2665
            });
2666
            title += ' ' + totalTime + 'ms';
2667
            if(moduleSelector) {
2668
              title += ' \'' + moduleSelector + '\'';
2669
            }
2670
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
2671
              console.groupCollapsed(title);
2672
              if(console.table) {
2673
                console.table(performance);
2674
              }
2675
              else {
2676
                $.each(performance, function(index, data) {
2677
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
2678
                });
2679
              }
2680
              console.groupEnd();
2681
            }
2682
            performance = [];
2683
          }
2684
        },
2685
        invoke: function(query, passedArguments, context) {
2686
          var
2687
            object = instance,
2688
            maxDepth,
2689
            found,
2690
            response
2691
          ;
2692
          passedArguments = passedArguments || queryArguments;
2693
          context         = element         || context;
2694
          if(typeof query == 'string' && object !== undefined) {
2695
            query    = query.split(/[\. ]/);
2696
            maxDepth = query.length - 1;
2697
            $.each(query, function(depth, value) {
2698
              var camelCaseValue = (depth != maxDepth)
2699
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
2700
                : query
2701
              ;
2702
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
2703
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
2704
              }
2705
              else if( object[camelCaseValue] !== undefined ) {
2706
                found = object[camelCaseValue];
2707
                return false;
2708
              }
2709
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
2710
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
2711
              }
2712
              else if( object[value] !== undefined ) {
2713
                found = object[value];
2714
                return false;
2715
              }
2716
              else {
2717
                module.error(error.method, query);
2718
                return false;
2719
              }
2720
            });
2721
          }
2722
          if ( $.isFunction( found ) ) {
2723
            response = found.apply(context, passedArguments);
2724
          }
2725
          else if(found !== undefined) {
2726
            response = found;
2727
          }
2728
          if($.isArray(returnedValue)) {
2729
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 2725 is false. Are you sure the function push handles undefined variables?
Loading history...
2730
          }
2731
          else if(returnedValue !== undefined) {
2732
            returnedValue = [returnedValue, response];
2733
          }
2734
          else if(response !== undefined) {
2735
            returnedValue = response;
2736
          }
2737
          return found;
2738
        }
2739
      };
2740
      if(methodInvoked) {
2741
        if(instance === undefined) {
2742
          module.initialize();
2743
        }
2744
        module.invoke(query);
2745
      }
2746
      else {
2747
        if(instance !== undefined) {
2748
          instance.invoke('destroy');
2749
        }
2750
        module.initialize();
2751
      }
2752
    })
2753
  ;
2754
  return (returnedValue !== undefined)
2755
    ? returnedValue
2756
    : this
2757
  ;
2758
};
2759
2760
$.fn.accordion.settings = {
2761
2762
  name            : 'Accordion',
2763
  namespace       : 'accordion',
2764
2765
  silent          : false,
2766
  debug           : false,
2767
  verbose         : false,
2768
  performance     : true,
2769
2770
  on              : 'click', // event on title that opens accordion
2771
2772
  observeChanges  : true,  // whether accordion should automatically refresh on DOM insertion
2773
2774
  exclusive       : true,  // whether a single accordion content panel should be open at once
2775
  collapsible     : true,  // whether accordion content can be closed
2776
  closeNested     : false, // whether nested content should be closed when a panel is closed
2777
  animateChildren : true,  // whether children opacity should be animated
2778
2779
  duration        : 350, // duration of animation
2780
  easing          : 'easeOutQuad', // easing equation for animation
2781
2782
2783
  onOpening       : function(){}, // callback before open animation
2784
  onOpen          : function(){}, // callback after open animation
2785
  onClosing       : function(){}, // callback before closing animation
2786
  onClose         : function(){}, // callback after closing animation
2787
  onChange        : function(){}, // callback after closing or opening animation
2788
2789
  error: {
2790
    method : 'The method you called is not defined'
2791
  },
2792
2793
  className   : {
2794
    active    : 'active',
2795
    animating : 'animating'
2796
  },
2797
2798
  selector    : {
2799
    accordion : '.accordion',
2800
    title     : '.title',
2801
    trigger   : '.title',
2802
    content   : '.content'
2803
  }
2804
2805
};
2806
2807
// Adds easing
2808
$.extend( $.easing, {
2809
  easeOutQuad: function (x, t, b, c, d) {
2810
    return -c *(t/=d)*(t-2) + b;
2811
  }
2812
});
2813
2814
})( jQuery, window, document );
2815
2816
2817
/*!
2818
 * # Semantic UI 2.2.11 - Checkbox
2819
 * http://github.com/semantic-org/semantic-ui/
2820
 *
2821
 *
2822
 * Released under the MIT license
2823
 * http://opensource.org/licenses/MIT
2824
 *
2825
 */
2826
2827 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2828
2829
"use strict";
2830
2831
window = (typeof window != 'undefined' && window.Math == Math)
2832
  ? window
2833
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
2834
    ? self
2835
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
2836
;
2837
2838
$.fn.checkbox = function(parameters) {
2839
  var
2840
    $allModules    = $(this),
2841
    moduleSelector = $allModules.selector || '',
2842
2843
    time           = new Date().getTime(),
2844
    performance    = [],
2845
2846
    query          = arguments[0],
2847
    methodInvoked  = (typeof query == 'string'),
2848
    queryArguments = [].slice.call(arguments, 1),
2849
    returnedValue
2850
  ;
2851
2852
  $allModules
2853
    .each(function() {
2854
      var
2855
        settings        = $.extend(true, {}, $.fn.checkbox.settings, parameters),
2856
2857
        className       = settings.className,
2858
        namespace       = settings.namespace,
2859
        selector        = settings.selector,
2860
        error           = settings.error,
2861
2862
        eventNamespace  = '.' + namespace,
2863
        moduleNamespace = 'module-' + namespace,
2864
2865
        $module         = $(this),
2866
        $label          = $(this).children(selector.label),
2867
        $input          = $(this).children(selector.input),
2868
        input           = $input[0],
2869
2870
        initialLoad     = false,
2871
        shortcutPressed = false,
2872
        instance        = $module.data(moduleNamespace),
2873
2874
        observer,
2875
        element         = this,
2876
        module
2877
      ;
2878
2879
      module      = {
2880
2881
        initialize: function() {
2882
          module.verbose('Initializing checkbox', settings);
2883
2884
          module.create.label();
2885
          module.bind.events();
2886
2887
          module.set.tabbable();
2888
          module.hide.input();
2889
2890
          module.observeChanges();
2891
          module.instantiate();
2892
          module.setup();
2893
        },
2894
2895
        instantiate: function() {
2896
          module.verbose('Storing instance of module', module);
2897
          instance = module;
2898
          $module
2899
            .data(moduleNamespace, module)
2900
          ;
2901
        },
2902
2903
        destroy: function() {
2904
          module.verbose('Destroying module');
2905
          module.unbind.events();
2906
          module.show.input();
2907
          $module.removeData(moduleNamespace);
2908
        },
2909
2910
        fix: {
2911
          reference: function() {
2912
            if( $module.is(selector.input) ) {
2913
              module.debug('Behavior called on <input> adjusting invoked element');
2914
              $module = $module.closest(selector.checkbox);
2915
              module.refresh();
2916
            }
2917
          }
2918
        },
2919
2920
        setup: function() {
2921
          module.set.initialLoad();
2922
          if( module.is.indeterminate() ) {
2923
            module.debug('Initial value is indeterminate');
2924
            module.indeterminate();
2925
          }
2926
          else if( module.is.checked() ) {
2927
            module.debug('Initial value is checked');
2928
            module.check();
2929
          }
2930
          else {
2931
            module.debug('Initial value is unchecked');
2932
            module.uncheck();
2933
          }
2934
          module.remove.initialLoad();
2935
        },
2936
2937
        refresh: function() {
2938
          $label = $module.children(selector.label);
2939
          $input = $module.children(selector.input);
2940
          input  = $input[0];
2941
        },
2942
2943
        hide: {
2944
          input: function() {
2945
            module.verbose('Modifying <input> z-index to be unselectable');
2946
            $input.addClass(className.hidden);
2947
          }
2948
        },
2949
        show: {
2950
          input: function() {
2951
            module.verbose('Modifying <input> z-index to be selectable');
2952
            $input.removeClass(className.hidden);
2953
          }
2954
        },
2955
2956
        observeChanges: function() {
2957
          if('MutationObserver' in window) {
2958
            observer = new MutationObserver(function(mutations) {
0 ignored issues
show
Bug introduced by
The variable MutationObserver seems to be never declared. If this is a global, consider adding a /** global: MutationObserver */ 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...
Unused Code introduced by
The parameter mutations is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
2959
              module.debug('DOM tree modified, updating selector cache');
2960
              module.refresh();
2961
            });
2962
            observer.observe(element, {
2963
              childList : true,
2964
              subtree   : true
2965
            });
2966
            module.debug('Setting up mutation observer', observer);
2967
          }
2968
        },
2969
2970
        attachEvents: function(selector, event) {
2971
          var
2972
            $element = $(selector)
2973
          ;
2974
          event = $.isFunction(module[event])
2975
            ? module[event]
2976
            : module.toggle
2977
          ;
2978
          if($element.length > 0) {
2979
            module.debug('Attaching checkbox events to element', selector, event);
2980
            $element
2981
              .on('click' + eventNamespace, event)
2982
            ;
2983
          }
2984
          else {
2985
            module.error(error.notFound);
2986
          }
2987
        },
2988
2989
        event: {
2990
          click: function(event) {
2991
            var
2992
              $target = $(event.target)
2993
            ;
2994
            if( $target.is(selector.input) ) {
2995
              module.verbose('Using default check action on initialized checkbox');
2996
              return;
2997
            }
2998
            if( $target.is(selector.link) ) {
2999
              module.debug('Clicking link inside checkbox, skipping toggle');
3000
              return;
3001
            }
3002
            module.toggle();
3003
            $input.focus();
3004
            event.preventDefault();
3005
          },
3006
          keydown: function(event) {
3007
            var
3008
              key     = event.which,
3009
              keyCode = {
3010
                enter  : 13,
3011
                space  : 32,
3012
                escape : 27
3013
              }
3014
            ;
3015
            if(key == keyCode.escape) {
3016
              module.verbose('Escape key pressed blurring field');
3017
              $input.blur();
3018
              shortcutPressed = true;
3019
            }
3020
            else if(!event.ctrlKey && ( key == keyCode.space || key == keyCode.enter) ) {
3021
              module.verbose('Enter/space key pressed, toggling checkbox');
3022
              module.toggle();
3023
              shortcutPressed = true;
3024
            }
3025
            else {
3026
              shortcutPressed = false;
3027
            }
3028
          },
3029
          keyup: function(event) {
3030
            if(shortcutPressed) {
3031
              event.preventDefault();
3032
            }
3033
          }
3034
        },
3035
3036
        check: function() {
3037
          if( !module.should.allowCheck() ) {
3038
            return;
3039
          }
3040
          module.debug('Checking checkbox', $input);
3041
          module.set.checked();
3042
          if( !module.should.ignoreCallbacks() ) {
3043
            settings.onChecked.call(input);
3044
            settings.onChange.call(input);
3045
          }
3046
        },
3047
3048
        uncheck: function() {
3049
          if( !module.should.allowUncheck() ) {
3050
            return;
3051
          }
3052
          module.debug('Unchecking checkbox');
3053
          module.set.unchecked();
3054
          if( !module.should.ignoreCallbacks() ) {
3055
            settings.onUnchecked.call(input);
3056
            settings.onChange.call(input);
3057
          }
3058
        },
3059
3060
        indeterminate: function() {
3061
          if( module.should.allowIndeterminate() ) {
3062
            module.debug('Checkbox is already indeterminate');
3063
            return;
3064
          }
3065
          module.debug('Making checkbox indeterminate');
3066
          module.set.indeterminate();
3067
          if( !module.should.ignoreCallbacks() ) {
3068
            settings.onIndeterminate.call(input);
3069
            settings.onChange.call(input);
3070
          }
3071
        },
3072
3073
        determinate: function() {
3074
          if( module.should.allowDeterminate() ) {
3075
            module.debug('Checkbox is already determinate');
3076
            return;
3077
          }
3078
          module.debug('Making checkbox determinate');
3079
          module.set.determinate();
3080
          if( !module.should.ignoreCallbacks() ) {
3081
            settings.onDeterminate.call(input);
3082
            settings.onChange.call(input);
3083
          }
3084
        },
3085
3086
        enable: function() {
3087
          if( module.is.enabled() ) {
3088
            module.debug('Checkbox is already enabled');
3089
            return;
3090
          }
3091
          module.debug('Enabling checkbox');
3092
          module.set.enabled();
3093
          settings.onEnable.call(input);
3094
          // preserve legacy callbacks
3095
          settings.onEnabled.call(input);
3096
        },
3097
3098
        disable: function() {
3099
          if( module.is.disabled() ) {
3100
            module.debug('Checkbox is already disabled');
3101
            return;
3102
          }
3103
          module.debug('Disabling checkbox');
3104
          module.set.disabled();
3105
          settings.onDisable.call(input);
3106
          // preserve legacy callbacks
3107
          settings.onDisabled.call(input);
3108
        },
3109
3110
        get: {
3111
          radios: function() {
3112
            var
3113
              name = module.get.name()
3114
            ;
3115
            return $('input[name="' + name + '"]').closest(selector.checkbox);
3116
          },
3117
          otherRadios: function() {
3118
            return module.get.radios().not($module);
3119
          },
3120
          name: function() {
3121
            return $input.attr('name');
3122
          }
3123
        },
3124
3125
        is: {
3126
          initialLoad: function() {
3127
            return initialLoad;
3128
          },
3129
          radio: function() {
3130
            return ($input.hasClass(className.radio) || $input.attr('type') == 'radio');
3131
          },
3132
          indeterminate: function() {
3133
            return $input.prop('indeterminate') !== undefined && $input.prop('indeterminate');
3134
          },
3135
          checked: function() {
3136
            return $input.prop('checked') !== undefined && $input.prop('checked');
3137
          },
3138
          disabled: function() {
3139
            return $input.prop('disabled') !== undefined && $input.prop('disabled');
3140
          },
3141
          enabled: function() {
3142
            return !module.is.disabled();
3143
          },
3144
          determinate: function() {
3145
            return !module.is.indeterminate();
3146
          },
3147
          unchecked: function() {
3148
            return !module.is.checked();
3149
          }
3150
        },
3151
3152
        should: {
3153
          allowCheck: function() {
3154
            if(module.is.determinate() && module.is.checked() && !module.should.forceCallbacks() ) {
3155
              module.debug('Should not allow check, checkbox is already checked');
3156
              return false;
3157
            }
3158
            if(settings.beforeChecked.apply(input) === false) {
3159
              module.debug('Should not allow check, beforeChecked cancelled');
3160
              return false;
3161
            }
3162
            return true;
3163
          },
3164
          allowUncheck: function() {
3165
            if(module.is.determinate() && module.is.unchecked() && !module.should.forceCallbacks() ) {
3166
              module.debug('Should not allow uncheck, checkbox is already unchecked');
3167
              return false;
3168
            }
3169
            if(settings.beforeUnchecked.apply(input) === false) {
3170
              module.debug('Should not allow uncheck, beforeUnchecked cancelled');
3171
              return false;
3172
            }
3173
            return true;
3174
          },
3175
          allowIndeterminate: function() {
3176
            if(module.is.indeterminate() && !module.should.forceCallbacks() ) {
3177
              module.debug('Should not allow indeterminate, checkbox is already indeterminate');
3178
              return false;
3179
            }
3180
            if(settings.beforeIndeterminate.apply(input) === false) {
3181
              module.debug('Should not allow indeterminate, beforeIndeterminate cancelled');
3182
              return false;
3183
            }
3184
            return true;
3185
          },
3186
          allowDeterminate: function() {
3187
            if(module.is.determinate() && !module.should.forceCallbacks() ) {
3188
              module.debug('Should not allow determinate, checkbox is already determinate');
3189
              return false;
3190
            }
3191
            if(settings.beforeDeterminate.apply(input) === false) {
3192
              module.debug('Should not allow determinate, beforeDeterminate cancelled');
3193
              return false;
3194
            }
3195
            return true;
3196
          },
3197
          forceCallbacks: function() {
3198
            return (module.is.initialLoad() && settings.fireOnInit);
3199
          },
3200
          ignoreCallbacks: function() {
3201
            return (initialLoad && !settings.fireOnInit);
3202
          }
3203
        },
3204
3205
        can: {
3206
          change: function() {
3207
            return !( $module.hasClass(className.disabled) || $module.hasClass(className.readOnly) || $input.prop('disabled') || $input.prop('readonly') );
3208
          },
3209
          uncheck: function() {
3210
            return (typeof settings.uncheckable === 'boolean')
3211
              ? settings.uncheckable
3212
              : !module.is.radio()
3213
            ;
3214
          }
3215
        },
3216
3217
        set: {
3218
          initialLoad: function() {
3219
            initialLoad = true;
3220
          },
3221
          checked: function() {
3222
            module.verbose('Setting class to checked');
3223
            $module
3224
              .removeClass(className.indeterminate)
3225
              .addClass(className.checked)
3226
            ;
3227
            if( module.is.radio() ) {
3228
              module.uncheckOthers();
3229
            }
3230
            if(!module.is.indeterminate() && module.is.checked()) {
3231
              module.debug('Input is already checked, skipping input property change');
3232
              return;
3233
            }
3234
            module.verbose('Setting state to checked', input);
3235
            $input
3236
              .prop('indeterminate', false)
3237
              .prop('checked', true)
3238
            ;
3239
            module.trigger.change();
3240
          },
3241
          unchecked: function() {
3242
            module.verbose('Removing checked class');
3243
            $module
3244
              .removeClass(className.indeterminate)
3245
              .removeClass(className.checked)
3246
            ;
3247
            if(!module.is.indeterminate() &&  module.is.unchecked() ) {
3248
              module.debug('Input is already unchecked');
3249
              return;
3250
            }
3251
            module.debug('Setting state to unchecked');
3252
            $input
3253
              .prop('indeterminate', false)
3254
              .prop('checked', false)
3255
            ;
3256
            module.trigger.change();
3257
          },
3258
          indeterminate: function() {
3259
            module.verbose('Setting class to indeterminate');
3260
            $module
3261
              .addClass(className.indeterminate)
3262
            ;
3263
            if( module.is.indeterminate() ) {
3264
              module.debug('Input is already indeterminate, skipping input property change');
3265
              return;
3266
            }
3267
            module.debug('Setting state to indeterminate');
3268
            $input
3269
              .prop('indeterminate', true)
3270
            ;
3271
            module.trigger.change();
3272
          },
3273
          determinate: function() {
3274
            module.verbose('Removing indeterminate class');
3275
            $module
3276
              .removeClass(className.indeterminate)
3277
            ;
3278
            if( module.is.determinate() ) {
3279
              module.debug('Input is already determinate, skipping input property change');
3280
              return;
3281
            }
3282
            module.debug('Setting state to determinate');
3283
            $input
3284
              .prop('indeterminate', false)
3285
            ;
3286
          },
3287
          disabled: function() {
3288
            module.verbose('Setting class to disabled');
3289
            $module
3290
              .addClass(className.disabled)
3291
            ;
3292
            if( module.is.disabled() ) {
3293
              module.debug('Input is already disabled, skipping input property change');
3294
              return;
3295
            }
3296
            module.debug('Setting state to disabled');
3297
            $input
3298
              .prop('disabled', 'disabled')
3299
            ;
3300
            module.trigger.change();
3301
          },
3302
          enabled: function() {
3303
            module.verbose('Removing disabled class');
3304
            $module.removeClass(className.disabled);
3305
            if( module.is.enabled() ) {
3306
              module.debug('Input is already enabled, skipping input property change');
3307
              return;
3308
            }
3309
            module.debug('Setting state to enabled');
3310
            $input
3311
              .prop('disabled', false)
3312
            ;
3313
            module.trigger.change();
3314
          },
3315
          tabbable: function() {
3316
            module.verbose('Adding tabindex to checkbox');
3317
            if( $input.attr('tabindex') === undefined) {
3318
              $input.attr('tabindex', 0);
3319
            }
3320
          }
3321
        },
3322
3323
        remove: {
3324
          initialLoad: function() {
3325
            initialLoad = false;
3326
          }
3327
        },
3328
3329
        trigger: {
3330
          change: function() {
3331
            var
3332
              events       = document.createEvent('HTMLEvents'),
3333
              inputElement = $input[0]
3334
            ;
3335
            if(inputElement) {
3336
              module.verbose('Triggering native change event');
3337
              events.initEvent('change', true, false);
3338
              inputElement.dispatchEvent(events);
3339
            }
3340
          }
3341
        },
3342
3343
3344
        create: {
3345
          label: function() {
3346
            if($input.prevAll(selector.label).length > 0) {
3347
              $input.prev(selector.label).detach().insertAfter($input);
3348
              module.debug('Moving existing label', $label);
3349
            }
3350
            else if( !module.has.label() ) {
3351
              $label = $('<label>').insertAfter($input);
3352
              module.debug('Creating label', $label);
3353
            }
3354
          }
3355
        },
3356
3357
        has: {
3358
          label: function() {
3359
            return ($label.length > 0);
3360
          }
3361
        },
3362
3363
        bind: {
3364
          events: function() {
3365
            module.verbose('Attaching checkbox events');
3366
            $module
3367
              .on('click'   + eventNamespace, module.event.click)
3368
              .on('keydown' + eventNamespace, selector.input, module.event.keydown)
3369
              .on('keyup'   + eventNamespace, selector.input, module.event.keyup)
3370
            ;
3371
          }
3372
        },
3373
3374
        unbind: {
3375
          events: function() {
3376
            module.debug('Removing events');
3377
            $module
3378
              .off(eventNamespace)
3379
            ;
3380
          }
3381
        },
3382
3383
        uncheckOthers: function() {
3384
          var
3385
            $radios = module.get.otherRadios()
3386
          ;
3387
          module.debug('Unchecking other radios', $radios);
3388
          $radios.removeClass(className.checked);
3389
        },
3390
3391
        toggle: function() {
3392
          if( !module.can.change() ) {
3393
            if(!module.is.radio()) {
3394
              module.debug('Checkbox is read-only or disabled, ignoring toggle');
3395
            }
3396
            return;
3397
          }
3398
          if( module.is.indeterminate() || module.is.unchecked() ) {
3399
            module.debug('Currently unchecked');
3400
            module.check();
3401
          }
3402
          else if( module.is.checked() && module.can.uncheck() ) {
3403
            module.debug('Currently checked');
3404
            module.uncheck();
3405
          }
3406
        },
3407
        setting: function(name, value) {
3408
          module.debug('Changing setting', name, value);
3409
          if( $.isPlainObject(name) ) {
3410
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
3411
          }
3412
          else if(value !== undefined) {
3413
            if($.isPlainObject(settings[name])) {
3414
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
3415
            }
3416
            else {
3417
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
3418
            }
3419
          }
3420
          else {
3421
            return settings[name];
3422
          }
3423
        },
3424
        internal: function(name, value) {
3425
          if( $.isPlainObject(name) ) {
3426
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
3427
          }
3428
          else if(value !== undefined) {
3429
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
3430
          }
3431
          else {
3432
            return module[name];
3433
          }
3434
        },
3435
        debug: function() {
3436
          if(!settings.silent && settings.debug) {
3437
            if(settings.performance) {
3438
              module.performance.log(arguments);
3439
            }
3440
            else {
3441
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
3442
              module.debug.apply(console, arguments);
3443
            }
3444
          }
3445
        },
3446
        verbose: function() {
3447
          if(!settings.silent && settings.verbose && settings.debug) {
3448
            if(settings.performance) {
3449
              module.performance.log(arguments);
3450
            }
3451
            else {
3452
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
3453
              module.verbose.apply(console, arguments);
3454
            }
3455
          }
3456
        },
3457
        error: function() {
3458
          if(!settings.silent) {
3459
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
3460
            module.error.apply(console, arguments);
3461
          }
3462
        },
3463
        performance: {
3464
          log: function(message) {
3465
            var
3466
              currentTime,
3467
              executionTime,
3468
              previousTime
3469
            ;
3470
            if(settings.performance) {
3471
              currentTime   = new Date().getTime();
3472
              previousTime  = time || currentTime;
3473
              executionTime = currentTime - previousTime;
3474
              time          = currentTime;
3475
              performance.push({
3476
                'Name'           : message[0],
3477
                'Arguments'      : [].slice.call(message, 1) || '',
3478
                'Element'        : element,
3479
                'Execution Time' : executionTime
3480
              });
3481
            }
3482
            clearTimeout(module.performance.timer);
3483
            module.performance.timer = setTimeout(module.performance.display, 500);
3484
          },
3485
          display: function() {
3486
            var
3487
              title = settings.name + ':',
3488
              totalTime = 0
3489
            ;
3490
            time = false;
3491
            clearTimeout(module.performance.timer);
3492
            $.each(performance, function(index, data) {
3493
              totalTime += data['Execution Time'];
3494
            });
3495
            title += ' ' + totalTime + 'ms';
3496
            if(moduleSelector) {
3497
              title += ' \'' + moduleSelector + '\'';
3498
            }
3499
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
3500
              console.groupCollapsed(title);
3501
              if(console.table) {
3502
                console.table(performance);
3503
              }
3504
              else {
3505
                $.each(performance, function(index, data) {
3506
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
3507
                });
3508
              }
3509
              console.groupEnd();
3510
            }
3511
            performance = [];
3512
          }
3513
        },
3514
        invoke: function(query, passedArguments, context) {
3515
          var
3516
            object = instance,
3517
            maxDepth,
3518
            found,
3519
            response
3520
          ;
3521
          passedArguments = passedArguments || queryArguments;
3522
          context         = element         || context;
3523
          if(typeof query == 'string' && object !== undefined) {
3524
            query    = query.split(/[\. ]/);
3525
            maxDepth = query.length - 1;
3526
            $.each(query, function(depth, value) {
3527
              var camelCaseValue = (depth != maxDepth)
3528
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
3529
                : query
3530
              ;
3531
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
3532
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
3533
              }
3534
              else if( object[camelCaseValue] !== undefined ) {
3535
                found = object[camelCaseValue];
3536
                return false;
3537
              }
3538
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
3539
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
3540
              }
3541
              else if( object[value] !== undefined ) {
3542
                found = object[value];
3543
                return false;
3544
              }
3545
              else {
3546
                module.error(error.method, query);
3547
                return false;
3548
              }
3549
            });
3550
          }
3551
          if ( $.isFunction( found ) ) {
3552
            response = found.apply(context, passedArguments);
3553
          }
3554
          else if(found !== undefined) {
3555
            response = found;
3556
          }
3557
          if($.isArray(returnedValue)) {
3558
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 3554 is false. Are you sure the function push handles undefined variables?
Loading history...
3559
          }
3560
          else if(returnedValue !== undefined) {
3561
            returnedValue = [returnedValue, response];
3562
          }
3563
          else if(response !== undefined) {
3564
            returnedValue = response;
3565
          }
3566
          return found;
3567
        }
3568
      };
3569
3570
      if(methodInvoked) {
3571
        if(instance === undefined) {
3572
          module.initialize();
3573
        }
3574
        module.invoke(query);
3575
      }
3576
      else {
3577
        if(instance !== undefined) {
3578
          instance.invoke('destroy');
3579
        }
3580
        module.initialize();
3581
      }
3582
    })
3583
  ;
3584
3585
  return (returnedValue !== undefined)
3586
    ? returnedValue
3587
    : this
3588
  ;
3589
};
3590
3591
$.fn.checkbox.settings = {
3592
3593
  name                : 'Checkbox',
3594
  namespace           : 'checkbox',
3595
3596
  silent              : false,
3597
  debug               : false,
3598
  verbose             : true,
3599
  performance         : true,
3600
3601
  // delegated event context
3602
  uncheckable         : 'auto',
3603
  fireOnInit          : false,
3604
3605
  onChange            : function(){},
3606
3607
  beforeChecked       : function(){},
3608
  beforeUnchecked     : function(){},
3609
  beforeDeterminate   : function(){},
3610
  beforeIndeterminate : function(){},
3611
3612
  onChecked           : function(){},
3613
  onUnchecked         : function(){},
3614
3615
  onDeterminate       : function() {},
3616
  onIndeterminate     : function() {},
3617
3618
  onEnable            : function(){},
3619
  onDisable           : function(){},
3620
3621
  // preserve misspelled callbacks (will be removed in 3.0)
3622
  onEnabled           : function(){},
3623
  onDisabled          : function(){},
3624
3625
  className       : {
3626
    checked       : 'checked',
3627
    indeterminate : 'indeterminate',
3628
    disabled      : 'disabled',
3629
    hidden        : 'hidden',
3630
    radio         : 'radio',
3631
    readOnly      : 'read-only'
3632
  },
3633
3634
  error     : {
3635
    method       : 'The method you called is not defined'
3636
  },
3637
3638
  selector : {
3639
    checkbox : '.ui.checkbox',
3640
    label    : 'label, .box',
3641
    input    : 'input[type="checkbox"], input[type="radio"]',
3642
    link     : 'a[href]'
3643
  }
3644
3645
};
3646
3647
})( jQuery, window, document );
3648
3649
/*!
3650
 * # Semantic UI 2.2.11 - Dimmer
3651
 * http://github.com/semantic-org/semantic-ui/
3652
 *
3653
 *
3654
 * Released under the MIT license
3655
 * http://opensource.org/licenses/MIT
3656
 *
3657
 */
3658
3659 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
3660
3661
"use strict";
3662
3663
window = (typeof window != 'undefined' && window.Math == Math)
0 ignored issues
show
Unused Code introduced by
The assignment to variable window seems to be never used. Consider removing it.
Loading history...
3664
  ? window
3665
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
3666
    ? self
3667
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
3668
;
3669
3670
$.fn.dimmer = function(parameters) {
3671
  var
3672
    $allModules     = $(this),
3673
3674
    time            = new Date().getTime(),
3675
    performance     = [],
3676
3677
    query           = arguments[0],
3678
    methodInvoked   = (typeof query == 'string'),
3679
    queryArguments  = [].slice.call(arguments, 1),
3680
3681
    returnedValue
3682
  ;
3683
3684
  $allModules
3685
    .each(function() {
3686
      var
3687
        settings        = ( $.isPlainObject(parameters) )
3688
          ? $.extend(true, {}, $.fn.dimmer.settings, parameters)
3689
          : $.extend({}, $.fn.dimmer.settings),
3690
3691
        selector        = settings.selector,
3692
        namespace       = settings.namespace,
3693
        className       = settings.className,
3694
        error           = settings.error,
3695
3696
        eventNamespace  = '.' + namespace,
3697
        moduleNamespace = 'module-' + namespace,
3698
        moduleSelector  = $allModules.selector || '',
3699
3700
        clickEvent      = ('ontouchstart' in document.documentElement)
3701
          ? 'touchstart'
3702
          : 'click',
3703
3704
        $module = $(this),
3705
        $dimmer,
3706
        $dimmable,
3707
3708
        element   = this,
3709
        instance  = $module.data(moduleNamespace),
3710
        module
3711
      ;
3712
3713
      module = {
3714
3715
        preinitialize: function() {
3716
          if( module.is.dimmer() ) {
3717
3718
            $dimmable = $module.parent();
3719
            $dimmer   = $module;
3720
          }
3721
          else {
3722
            $dimmable = $module;
3723
            if( module.has.dimmer() ) {
3724
              if(settings.dimmerName) {
3725
                $dimmer = $dimmable.find(selector.dimmer).filter('.' + settings.dimmerName);
3726
              }
3727
              else {
3728
                $dimmer = $dimmable.find(selector.dimmer);
3729
              }
3730
            }
3731
            else {
3732
              $dimmer = module.create();
3733
            }
3734
            module.set.variation();
3735
          }
3736
        },
3737
3738
        initialize: function() {
3739
          module.debug('Initializing dimmer', settings);
3740
3741
          module.bind.events();
3742
          module.set.dimmable();
3743
          module.instantiate();
3744
        },
3745
3746
        instantiate: function() {
3747
          module.verbose('Storing instance of module', module);
3748
          instance = module;
3749
          $module
3750
            .data(moduleNamespace, instance)
3751
          ;
3752
        },
3753
3754
        destroy: function() {
3755
          module.verbose('Destroying previous module', $dimmer);
3756
          module.unbind.events();
3757
          module.remove.variation();
3758
          $dimmable
3759
            .off(eventNamespace)
3760
          ;
3761
        },
3762
3763
        bind: {
3764
          events: function() {
3765
            if(settings.on == 'hover') {
3766
              $dimmable
3767
                .on('mouseenter' + eventNamespace, module.show)
3768
                .on('mouseleave' + eventNamespace, module.hide)
3769
              ;
3770
            }
3771
            else if(settings.on == 'click') {
3772
              $dimmable
3773
                .on(clickEvent + eventNamespace, module.toggle)
3774
              ;
3775
            }
3776
            if( module.is.page() ) {
3777
              module.debug('Setting as a page dimmer', $dimmable);
3778
              module.set.pageDimmer();
3779
            }
3780
3781
            if( module.is.closable() ) {
3782
              module.verbose('Adding dimmer close event', $dimmer);
3783
              $dimmable
3784
                .on(clickEvent + eventNamespace, selector.dimmer, module.event.click)
3785
              ;
3786
            }
3787
          }
3788
        },
3789
3790
        unbind: {
3791
          events: function() {
3792
            $module
3793
              .removeData(moduleNamespace)
3794
            ;
3795
            $dimmable
3796
              .off(eventNamespace)
3797
            ;
3798
          }
3799
        },
3800
3801
        event: {
3802
          click: function(event) {
3803
            module.verbose('Determining if event occured on dimmer', event);
3804
            if( $dimmer.find(event.target).length === 0 || $(event.target).is(selector.content) ) {
3805
              module.hide();
3806
              event.stopImmediatePropagation();
3807
            }
3808
          }
3809
        },
3810
3811
        addContent: function(element) {
3812
          var
3813
            $content = $(element)
3814
          ;
3815
          module.debug('Add content to dimmer', $content);
3816
          if($content.parent()[0] !== $dimmer[0]) {
3817
            $content.detach().appendTo($dimmer);
3818
          }
3819
        },
3820
3821
        create: function() {
3822
          var
3823
            $element = $( settings.template.dimmer() )
3824
          ;
3825
          if(settings.dimmerName) {
3826
            module.debug('Creating named dimmer', settings.dimmerName);
3827
            $element.addClass(settings.dimmerName);
3828
          }
3829
          $element
3830
            .appendTo($dimmable)
3831
          ;
3832
          return $element;
3833
        },
3834
3835
        show: function(callback) {
3836
          callback = $.isFunction(callback)
3837
            ? callback
3838
            : function(){}
3839
          ;
3840
          module.debug('Showing dimmer', $dimmer, settings);
3841
          if( (!module.is.dimmed() || module.is.animating()) && module.is.enabled() ) {
3842
            module.animate.show(callback);
3843
            settings.onShow.call(element);
3844
            settings.onChange.call(element);
3845
          }
3846
          else {
3847
            module.debug('Dimmer is already shown or disabled');
3848
          }
3849
        },
3850
3851
        hide: function(callback) {
3852
          callback = $.isFunction(callback)
3853
            ? callback
3854
            : function(){}
3855
          ;
3856
          if( module.is.dimmed() || module.is.animating() ) {
3857
            module.debug('Hiding dimmer', $dimmer);
3858
            module.animate.hide(callback);
3859
            settings.onHide.call(element);
3860
            settings.onChange.call(element);
3861
          }
3862
          else {
3863
            module.debug('Dimmer is not visible');
3864
          }
3865
        },
3866
3867
        toggle: function() {
3868
          module.verbose('Toggling dimmer visibility', $dimmer);
3869
          if( !module.is.dimmed() ) {
3870
            module.show();
3871
          }
3872
          else {
3873
            module.hide();
3874
          }
3875
        },
3876
3877
        animate: {
3878
          show: function(callback) {
3879
            callback = $.isFunction(callback)
3880
              ? callback
3881
              : function(){}
3882
            ;
3883
            if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) {
3884
              if(settings.opacity !== 'auto') {
3885
                module.set.opacity();
3886
              }
3887
              $dimmer
3888
                .transition({
3889
                  animation   : settings.transition + ' in',
3890
                  queue       : false,
3891
                  duration    : module.get.duration(),
3892
                  useFailSafe : true,
3893
                  onStart     : function() {
3894
                    module.set.dimmed();
3895
                  },
3896
                  onComplete  : function() {
3897
                    module.set.active();
3898
                    callback();
3899
                  }
3900
                })
3901
              ;
3902
            }
3903
            else {
3904
              module.verbose('Showing dimmer animation with javascript');
3905
              module.set.dimmed();
3906
              if(settings.opacity == 'auto') {
3907
                settings.opacity = 0.8;
3908
              }
3909
              $dimmer
3910
                .stop()
3911
                .css({
3912
                  opacity : 0,
3913
                  width   : '100%',
3914
                  height  : '100%'
3915
                })
3916
                .fadeTo(module.get.duration(), settings.opacity, function() {
3917
                  $dimmer.removeAttr('style');
3918
                  module.set.active();
3919
                  callback();
3920
                })
3921
              ;
3922
            }
3923
          },
3924
          hide: function(callback) {
3925
            callback = $.isFunction(callback)
3926
              ? callback
3927
              : function(){}
3928
            ;
3929
            if(settings.useCSS && $.fn.transition !== undefined && $dimmer.transition('is supported')) {
3930
              module.verbose('Hiding dimmer with css');
3931
              $dimmer
3932
                .transition({
3933
                  animation   : settings.transition + ' out',
3934
                  queue       : false,
3935
                  duration    : module.get.duration(),
3936
                  useFailSafe : true,
3937
                  onStart     : function() {
3938
                    module.remove.dimmed();
3939
                  },
3940
                  onComplete  : function() {
3941
                    module.remove.active();
3942
                    callback();
3943
                  }
3944
                })
3945
              ;
3946
            }
3947
            else {
3948
              module.verbose('Hiding dimmer with javascript');
3949
              module.remove.dimmed();
3950
              $dimmer
3951
                .stop()
3952
                .fadeOut(module.get.duration(), function() {
3953
                  module.remove.active();
3954
                  $dimmer.removeAttr('style');
3955
                  callback();
3956
                })
3957
              ;
3958
            }
3959
          }
3960
        },
3961
3962
        get: {
3963
          dimmer: function() {
3964
            return $dimmer;
3965
          },
3966
          duration: function() {
3967
            if(typeof settings.duration == 'object') {
3968
              if( module.is.active() ) {
3969
                return settings.duration.hide;
3970
              }
3971
              else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3972
                return settings.duration.show;
3973
              }
3974
            }
3975
            return settings.duration;
3976
          }
3977
        },
3978
3979
        has: {
3980
          dimmer: function() {
3981
            if(settings.dimmerName) {
3982
              return ($module.find(selector.dimmer).filter('.' + settings.dimmerName).length > 0);
3983
            }
3984
            else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
3985
              return ( $module.find(selector.dimmer).length > 0 );
3986
            }
3987
          }
3988
        },
3989
3990
        is: {
3991
          active: function() {
3992
            return $dimmer.hasClass(className.active);
3993
          },
3994
          animating: function() {
3995
            return ( $dimmer.is(':animated') || $dimmer.hasClass(className.animating) );
3996
          },
3997
          closable: function() {
3998
            if(settings.closable == 'auto') {
3999
              if(settings.on == 'hover') {
4000
                return false;
4001
              }
4002
              return true;
4003
            }
4004
            return settings.closable;
4005
          },
4006
          dimmer: function() {
4007
            return $module.hasClass(className.dimmer);
4008
          },
4009
          dimmable: function() {
4010
            return $module.hasClass(className.dimmable);
4011
          },
4012
          dimmed: function() {
4013
            return $dimmable.hasClass(className.dimmed);
4014
          },
4015
          disabled: function() {
4016
            return $dimmable.hasClass(className.disabled);
4017
          },
4018
          enabled: function() {
4019
            return !module.is.disabled();
4020
          },
4021
          page: function () {
4022
            return $dimmable.is('body');
4023
          },
4024
          pageDimmer: function() {
4025
            return $dimmer.hasClass(className.pageDimmer);
4026
          }
4027
        },
4028
4029
        can: {
4030
          show: function() {
4031
            return !$dimmer.hasClass(className.disabled);
4032
          }
4033
        },
4034
4035
        set: {
4036
          opacity: function(opacity) {
4037
            var
4038
              color      = $dimmer.css('background-color'),
4039
              colorArray = color.split(','),
4040
              isRGB      = (colorArray && colorArray.length == 3),
4041
              isRGBA     = (colorArray && colorArray.length == 4)
4042
            ;
4043
            opacity    = settings.opacity === 0 ? 0 : settings.opacity || opacity;
4044
            if(isRGB || isRGBA) {
4045
              colorArray[3] = opacity + ')';
4046
              color         = colorArray.join(',');
4047
            }
4048
            else {
4049
              color = 'rgba(0, 0, 0, ' + opacity + ')';
4050
            }
4051
            module.debug('Setting opacity to', opacity);
4052
            $dimmer.css('background-color', color);
4053
          },
4054
          active: function() {
4055
            $dimmer.addClass(className.active);
4056
          },
4057
          dimmable: function() {
4058
            $dimmable.addClass(className.dimmable);
4059
          },
4060
          dimmed: function() {
4061
            $dimmable.addClass(className.dimmed);
4062
          },
4063
          pageDimmer: function() {
4064
            $dimmer.addClass(className.pageDimmer);
4065
          },
4066
          disabled: function() {
4067
            $dimmer.addClass(className.disabled);
4068
          },
4069
          variation: function(variation) {
4070
            variation = variation || settings.variation;
4071
            if(variation) {
4072
              $dimmer.addClass(variation);
4073
            }
4074
          }
4075
        },
4076
4077
        remove: {
4078
          active: function() {
4079
            $dimmer
4080
              .removeClass(className.active)
4081
            ;
4082
          },
4083
          dimmed: function() {
4084
            $dimmable.removeClass(className.dimmed);
4085
          },
4086
          disabled: function() {
4087
            $dimmer.removeClass(className.disabled);
4088
          },
4089
          variation: function(variation) {
4090
            variation = variation || settings.variation;
4091
            if(variation) {
4092
              $dimmer.removeClass(variation);
4093
            }
4094
          }
4095
        },
4096
4097
        setting: function(name, value) {
4098
          module.debug('Changing setting', name, value);
4099
          if( $.isPlainObject(name) ) {
4100
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
4101
          }
4102
          else if(value !== undefined) {
4103
            if($.isPlainObject(settings[name])) {
4104
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
4105
            }
4106
            else {
4107
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
4108
            }
4109
          }
4110
          else {
4111
            return settings[name];
4112
          }
4113
        },
4114
        internal: function(name, value) {
4115
          if( $.isPlainObject(name) ) {
4116
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
4117
          }
4118
          else if(value !== undefined) {
4119
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
4120
          }
4121
          else {
4122
            return module[name];
4123
          }
4124
        },
4125
        debug: function() {
4126
          if(!settings.silent && settings.debug) {
4127
            if(settings.performance) {
4128
              module.performance.log(arguments);
4129
            }
4130
            else {
4131
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
4132
              module.debug.apply(console, arguments);
4133
            }
4134
          }
4135
        },
4136
        verbose: function() {
4137
          if(!settings.silent && settings.verbose && settings.debug) {
4138
            if(settings.performance) {
4139
              module.performance.log(arguments);
4140
            }
4141
            else {
4142
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
4143
              module.verbose.apply(console, arguments);
4144
            }
4145
          }
4146
        },
4147
        error: function() {
4148
          if(!settings.silent) {
4149
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
4150
            module.error.apply(console, arguments);
4151
          }
4152
        },
4153
        performance: {
4154
          log: function(message) {
4155
            var
4156
              currentTime,
4157
              executionTime,
4158
              previousTime
4159
            ;
4160
            if(settings.performance) {
4161
              currentTime   = new Date().getTime();
4162
              previousTime  = time || currentTime;
4163
              executionTime = currentTime - previousTime;
4164
              time          = currentTime;
4165
              performance.push({
4166
                'Name'           : message[0],
4167
                'Arguments'      : [].slice.call(message, 1) || '',
4168
                'Element'        : element,
4169
                'Execution Time' : executionTime
4170
              });
4171
            }
4172
            clearTimeout(module.performance.timer);
4173
            module.performance.timer = setTimeout(module.performance.display, 500);
4174
          },
4175
          display: function() {
4176
            var
4177
              title = settings.name + ':',
4178
              totalTime = 0
4179
            ;
4180
            time = false;
4181
            clearTimeout(module.performance.timer);
4182
            $.each(performance, function(index, data) {
4183
              totalTime += data['Execution Time'];
4184
            });
4185
            title += ' ' + totalTime + 'ms';
4186
            if(moduleSelector) {
4187
              title += ' \'' + moduleSelector + '\'';
4188
            }
4189
            if($allModules.length > 1) {
4190
              title += ' ' + '(' + $allModules.length + ')';
4191
            }
4192
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
4193
              console.groupCollapsed(title);
4194
              if(console.table) {
4195
                console.table(performance);
4196
              }
4197
              else {
4198
                $.each(performance, function(index, data) {
4199
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
4200
                });
4201
              }
4202
              console.groupEnd();
4203
            }
4204
            performance = [];
4205
          }
4206
        },
4207
        invoke: function(query, passedArguments, context) {
4208
          var
4209
            object = instance,
4210
            maxDepth,
4211
            found,
4212
            response
4213
          ;
4214
          passedArguments = passedArguments || queryArguments;
4215
          context         = element         || context;
4216
          if(typeof query == 'string' && object !== undefined) {
4217
            query    = query.split(/[\. ]/);
4218
            maxDepth = query.length - 1;
4219
            $.each(query, function(depth, value) {
4220
              var camelCaseValue = (depth != maxDepth)
4221
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
4222
                : query
4223
              ;
4224
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
4225
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
4226
              }
4227
              else if( object[camelCaseValue] !== undefined ) {
4228
                found = object[camelCaseValue];
4229
                return false;
4230
              }
4231
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
4232
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
4233
              }
4234
              else if( object[value] !== undefined ) {
4235
                found = object[value];
4236
                return false;
4237
              }
4238
              else {
4239
                module.error(error.method, query);
4240
                return false;
4241
              }
4242
            });
4243
          }
4244
          if ( $.isFunction( found ) ) {
4245
            response = found.apply(context, passedArguments);
4246
          }
4247
          else if(found !== undefined) {
4248
            response = found;
4249
          }
4250
          if($.isArray(returnedValue)) {
4251
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 4247 is false. Are you sure the function push handles undefined variables?
Loading history...
4252
          }
4253
          else if(returnedValue !== undefined) {
4254
            returnedValue = [returnedValue, response];
4255
          }
4256
          else if(response !== undefined) {
4257
            returnedValue = response;
4258
          }
4259
          return found;
4260
        }
4261
      };
4262
4263
      module.preinitialize();
4264
4265
      if(methodInvoked) {
4266
        if(instance === undefined) {
4267
          module.initialize();
4268
        }
4269
        module.invoke(query);
4270
      }
4271
      else {
4272
        if(instance !== undefined) {
4273
          instance.invoke('destroy');
4274
        }
4275
        module.initialize();
4276
      }
4277
    })
4278
  ;
4279
4280
  return (returnedValue !== undefined)
4281
    ? returnedValue
4282
    : this
4283
  ;
4284
};
4285
4286
$.fn.dimmer.settings = {
4287
4288
  name        : 'Dimmer',
4289
  namespace   : 'dimmer',
4290
4291
  silent      : false,
4292
  debug       : false,
4293
  verbose     : false,
4294
  performance : true,
4295
4296
  // name to distinguish between multiple dimmers in context
4297
  dimmerName  : false,
4298
4299
  // whether to add a variation type
4300
  variation   : false,
4301
4302
  // whether to bind close events
4303
  closable    : 'auto',
4304
4305
  // whether to use css animations
4306
  useCSS      : true,
4307
4308
  // css animation to use
4309
  transition  : 'fade',
4310
4311
  // event to bind to
4312
  on          : false,
4313
4314
  // overriding opacity value
4315
  opacity     : 'auto',
4316
4317
  // transition durations
4318
  duration    : {
4319
    show : 500,
4320
    hide : 500
4321
  },
4322
4323
  onChange    : function(){},
4324
  onShow      : function(){},
4325
  onHide      : function(){},
4326
4327
  error   : {
4328
    method   : 'The method you called is not defined.'
4329
  },
4330
4331
  className : {
4332
    active     : 'active',
4333
    animating  : 'animating',
4334
    dimmable   : 'dimmable',
4335
    dimmed     : 'dimmed',
4336
    dimmer     : 'dimmer',
4337
    disabled   : 'disabled',
4338
    hide       : 'hide',
4339
    pageDimmer : 'page',
4340
    show       : 'show'
4341
  },
4342
4343
  selector: {
4344
    dimmer   : '> .ui.dimmer',
4345
    content  : '.ui.dimmer > .content, .ui.dimmer > .content > .center'
4346
  },
4347
4348
  template: {
4349
    dimmer: function() {
4350
     return $('<div />').attr('class', 'ui dimmer');
4351
    }
4352
  }
4353
4354
};
4355
4356
})( jQuery, window, document );
4357
4358
/*!
4359
 * # Semantic UI 2.2.11 - Dropdown
4360
 * http://github.com/semantic-org/semantic-ui/
4361
 *
4362
 *
4363
 * Released under the MIT license
4364
 * http://opensource.org/licenses/MIT
4365
 *
4366
 */
4367
4368 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
4369
4370
"use strict";
4371
4372
window = (typeof window != 'undefined' && window.Math == Math)
4373
  ? window
4374
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
4375
    ? self
4376
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
4377
;
4378
4379
$.fn.dropdown = function(parameters) {
4380
  var
4381
    $allModules    = $(this),
4382
    $document      = $(document),
4383
4384
    moduleSelector = $allModules.selector || '',
4385
4386
    hasTouch       = ('ontouchstart' in document.documentElement),
4387
    time           = new Date().getTime(),
4388
    performance    = [],
4389
4390
    query          = arguments[0],
4391
    methodInvoked  = (typeof query == 'string'),
4392
    queryArguments = [].slice.call(arguments, 1),
4393
    returnedValue
4394
  ;
4395
4396
  $allModules
4397
    .each(function(elementIndex) {
4398
      var
4399
        settings          = ( $.isPlainObject(parameters) )
4400
          ? $.extend(true, {}, $.fn.dropdown.settings, parameters)
4401
          : $.extend({}, $.fn.dropdown.settings),
4402
4403
        className       = settings.className,
4404
        message         = settings.message,
4405
        fields          = settings.fields,
4406
        keys            = settings.keys,
4407
        metadata        = settings.metadata,
4408
        namespace       = settings.namespace,
4409
        regExp          = settings.regExp,
4410
        selector        = settings.selector,
4411
        error           = settings.error,
4412
        templates       = settings.templates,
4413
4414
        eventNamespace  = '.' + namespace,
4415
        moduleNamespace = 'module-' + namespace,
4416
4417
        $module         = $(this),
4418
        $context        = $(settings.context),
4419
        $text           = $module.find(selector.text),
4420
        $search         = $module.find(selector.search),
4421
        $sizer          = $module.find(selector.sizer),
4422
        $input          = $module.find(selector.input),
4423
        $icon           = $module.find(selector.icon),
4424
4425
        $combo = ($module.prev().find(selector.text).length > 0)
4426
          ? $module.prev().find(selector.text)
4427
          : $module.prev(),
4428
4429
        $menu           = $module.children(selector.menu),
4430
        $item           = $menu.find(selector.item),
4431
4432
        activated       = false,
4433
        itemActivated   = false,
4434
        internalChange  = false,
4435
        element         = this,
4436
        instance        = $module.data(moduleNamespace),
4437
4438
        initialLoad,
4439
        pageLostFocus,
4440
        willRefocus,
4441
        elementNamespace,
4442
        id,
4443
        selectObserver,
4444
        menuObserver,
4445
        module
4446
      ;
4447
4448
      module = {
4449
4450
        initialize: function() {
4451
          module.debug('Initializing dropdown', settings);
4452
4453
          if( module.is.alreadySetup() ) {
4454
            module.setup.reference();
4455
          }
4456
          else {
4457
            module.setup.layout();
4458
            module.refreshData();
4459
4460
            module.save.defaults();
4461
            module.restore.selected();
4462
4463
            module.create.id();
4464
            module.bind.events();
4465
4466
            module.observeChanges();
4467
            module.instantiate();
4468
          }
4469
4470
        },
4471
4472
        instantiate: function() {
4473
          module.verbose('Storing instance of dropdown', module);
4474
          instance = module;
4475
          $module
4476
            .data(moduleNamespace, module)
4477
          ;
4478
        },
4479
4480
        destroy: function() {
4481
          module.verbose('Destroying previous dropdown', $module);
4482
          module.remove.tabbable();
4483
          $module
4484
            .off(eventNamespace)
4485
            .removeData(moduleNamespace)
4486
          ;
4487
          $menu
4488
            .off(eventNamespace)
4489
          ;
4490
          $document
4491
            .off(elementNamespace)
4492
          ;
4493
          module.disconnect.menuObserver();
4494
          module.disconnect.selectObserver();
4495
        },
4496
4497
        observeChanges: function() {
4498
          if('MutationObserver' in window) {
4499
            selectObserver = new MutationObserver(module.event.select.mutation);
0 ignored issues
show
Bug introduced by
The variable MutationObserver seems to be never declared. If this is a global, consider adding a /** global: MutationObserver */ 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...
4500
            menuObserver   = new MutationObserver(module.event.menu.mutation);
4501
            module.debug('Setting up mutation observer', selectObserver, menuObserver);
4502
            module.observe.select();
4503
            module.observe.menu();
4504
          }
4505
        },
4506
4507
        disconnect: {
4508
          menuObserver: function() {
4509
            if(menuObserver) {
4510
              menuObserver.disconnect();
4511
            }
4512
          },
4513
          selectObserver: function() {
4514
            if(selectObserver) {
4515
              selectObserver.disconnect();
4516
            }
4517
          }
4518
        },
4519
        observe: {
4520
          select: function() {
4521
            if(module.has.input()) {
4522
              selectObserver.observe($input[0], {
4523
                childList : true,
4524
                subtree   : true
4525
              });
4526
            }
4527
          },
4528
          menu: function() {
4529
            if(module.has.menu()) {
4530
              menuObserver.observe($menu[0], {
4531
                childList : true,
4532
                subtree   : true
4533
              });
4534
            }
4535
          }
4536
        },
4537
4538
        create: {
4539
          id: function() {
4540
            id = (Math.random().toString(16) + '000000000').substr(2, 8);
4541
            elementNamespace = '.' + id;
4542
            module.verbose('Creating unique id for element', id);
4543
          },
4544
          userChoice: function(values) {
4545
            var
4546
              $userChoices,
4547
              $userChoice,
4548
              isUserValue,
0 ignored issues
show
Unused Code introduced by
The variable isUserValue seems to be never used. Consider removing it.
Loading history...
4549
              html
4550
            ;
4551
            values = values || module.get.userValues();
4552
            if(!values) {
4553
              return false;
4554
            }
4555
            values = $.isArray(values)
4556
              ? values
4557
              : [values]
4558
            ;
4559
            $.each(values, function(index, value) {
4560
              if(module.get.item(value) === false) {
4561
                html         = settings.templates.addition( module.add.variables(message.addResult, value) );
4562
                $userChoice  = $('<div />')
4563
                  .html(html)
4564
                  .attr('data-' + metadata.value, value)
4565
                  .attr('data-' + metadata.text, value)
4566
                  .addClass(className.addition)
4567
                  .addClass(className.item)
4568
                ;
4569
                if(settings.hideAdditions) {
4570
                  $userChoice.addClass(className.hidden);
4571
                }
4572
                $userChoices = ($userChoices === undefined)
4573
                  ? $userChoice
4574
                  : $userChoices.add($userChoice)
4575
                ;
4576
                module.verbose('Creating user choices for value', value, $userChoice);
4577
              }
4578
            });
4579
            return $userChoices;
4580
          },
4581
          userLabels: function(value) {
4582
            var
4583
              userValues = module.get.userValues()
4584
            ;
4585
            if(userValues) {
4586
              module.debug('Adding user labels', userValues);
4587
              $.each(userValues, function(index, value) {
4588
                module.verbose('Adding custom user value');
4589
                module.add.label(value, value);
4590
              });
4591
            }
4592
          },
4593
          menu: function() {
4594
            $menu = $('<div />')
4595
              .addClass(className.menu)
4596
              .appendTo($module)
4597
            ;
4598
          },
4599
          sizer: function() {
4600
            $sizer = $('<span />')
4601
              .addClass(className.sizer)
4602
              .insertAfter($search)
4603
            ;
4604
          }
4605
        },
4606
4607
        search: function(query) {
4608
          query = (query !== undefined)
4609
            ? query
4610
            : module.get.query()
4611
          ;
4612
          module.verbose('Searching for query', query);
4613
          if(module.has.minCharacters(query)) {
4614
            module.filter(query);
4615
          }
4616
          else {
4617
            module.hide();
4618
          }
4619
        },
4620
4621
        select: {
4622
          firstUnfiltered: function() {
4623
            module.verbose('Selecting first non-filtered element');
4624
            module.remove.selectedItem();
4625
            $item
4626
              .not(selector.unselectable)
4627
              .not(selector.addition + selector.hidden)
4628
                .eq(0)
4629
                .addClass(className.selected)
4630
            ;
4631
          },
4632
          nextAvailable: function($selected) {
4633
            $selected = $selected.eq(0);
4634
            var
4635
              $nextAvailable = $selected.nextAll(selector.item).not(selector.unselectable).eq(0),
4636
              $prevAvailable = $selected.prevAll(selector.item).not(selector.unselectable).eq(0),
4637
              hasNext        = ($nextAvailable.length > 0)
4638
            ;
4639
            if(hasNext) {
4640
              module.verbose('Moving selection to', $nextAvailable);
4641
              $nextAvailable.addClass(className.selected);
4642
            }
4643
            else {
4644
              module.verbose('Moving selection to', $prevAvailable);
4645
              $prevAvailable.addClass(className.selected);
4646
            }
4647
          }
4648
        },
4649
4650
        setup: {
4651
          api: function() {
4652
            var
4653
              apiSettings = {
4654
                debug   : settings.debug,
4655
                urlData : {
4656
                  value : module.get.value(),
4657
                  query : module.get.query()
4658
                },
4659
                on    : false
4660
              }
4661
            ;
4662
            module.verbose('First request, initializing API');
4663
            $module
4664
              .api(apiSettings)
4665
            ;
4666
          },
4667
          layout: function() {
4668
            if( $module.is('select') ) {
4669
              module.setup.select();
4670
              module.setup.returnedObject();
4671
            }
4672
            if( !module.has.menu() ) {
4673
              module.create.menu();
4674
            }
4675
            if( module.is.search() && !module.has.search() ) {
4676
              module.verbose('Adding search input');
4677
              $search = $('<input />')
4678
                .addClass(className.search)
4679
                .prop('autocomplete', 'off')
4680
                .insertBefore($text)
4681
              ;
4682
            }
4683
            if( module.is.multiple() && module.is.searchSelection() && !module.has.sizer()) {
4684
              module.create.sizer();
4685
            }
4686
            if(settings.allowTab) {
4687
              module.set.tabbable();
4688
            }
4689
          },
4690
          select: function() {
4691
            var
4692
              selectValues  = module.get.selectValues()
4693
            ;
4694
            module.debug('Dropdown initialized on a select', selectValues);
4695
            if( $module.is('select') ) {
4696
              $input = $module;
4697
            }
4698
            // see if select is placed correctly already
4699
            if($input.parent(selector.dropdown).length > 0) {
4700
              module.debug('UI dropdown already exists. Creating dropdown menu only');
4701
              $module = $input.closest(selector.dropdown);
4702
              if( !module.has.menu() ) {
4703
                module.create.menu();
4704
              }
4705
              $menu = $module.children(selector.menu);
4706
              module.setup.menu(selectValues);
4707
            }
4708
            else {
4709
              module.debug('Creating entire dropdown from select');
4710
              $module = $('<div />')
4711
                .attr('class', $input.attr('class') )
4712
                .addClass(className.selection)
4713
                .addClass(className.dropdown)
4714
                .html( templates.dropdown(selectValues) )
4715
                .insertBefore($input)
4716
              ;
4717
              if($input.hasClass(className.multiple) && $input.prop('multiple') === false) {
4718
                module.error(error.missingMultiple);
4719
                $input.prop('multiple', true);
4720
              }
4721
              if($input.is('[multiple]')) {
4722
                module.set.multiple();
4723
              }
4724
              if ($input.prop('disabled')) {
4725
                module.debug('Disabling dropdown');
4726
                $module.addClass(className.disabled);
4727
              }
4728
              $input
4729
                .removeAttr('class')
4730
                .detach()
4731
                .prependTo($module)
4732
              ;
4733
            }
4734
            module.refresh();
4735
          },
4736
          menu: function(values) {
4737
            $menu.html( templates.menu(values, fields));
4738
            $item = $menu.find(selector.item);
4739
          },
4740
          reference: function() {
4741
            module.debug('Dropdown behavior was called on select, replacing with closest dropdown');
4742
            // replace module reference
4743
            $module = $module.parent(selector.dropdown);
4744
            module.refresh();
4745
            module.setup.returnedObject();
4746
            // invoke method in context of current instance
4747
            if(methodInvoked) {
4748
              instance = module;
4749
              module.invoke(query);
4750
            }
4751
          },
4752
          returnedObject: function() {
4753
            var
4754
              $firstModules = $allModules.slice(0, elementIndex),
4755
              $lastModules = $allModules.slice(elementIndex + 1)
4756
            ;
4757
            // adjust all modules to use correct reference
4758
            $allModules = $firstModules.add($module).add($lastModules);
4759
          }
4760
        },
4761
4762
        refresh: function() {
4763
          module.refreshSelectors();
4764
          module.refreshData();
4765
        },
4766
4767
        refreshItems: function() {
4768
          $item = $menu.find(selector.item);
4769
        },
4770
4771
        refreshSelectors: function() {
4772
          module.verbose('Refreshing selector cache');
4773
          $text   = $module.find(selector.text);
4774
          $search = $module.find(selector.search);
4775
          $input  = $module.find(selector.input);
4776
          $icon   = $module.find(selector.icon);
4777
          $combo  = ($module.prev().find(selector.text).length > 0)
4778
            ? $module.prev().find(selector.text)
4779
            : $module.prev()
4780
          ;
4781
          $menu    = $module.children(selector.menu);
4782
          $item    = $menu.find(selector.item);
4783
        },
4784
4785
        refreshData: function() {
4786
          module.verbose('Refreshing cached metadata');
4787
          $item
4788
            .removeData(metadata.text)
4789
            .removeData(metadata.value)
4790
          ;
4791
        },
4792
4793
        clearData: function() {
4794
          module.verbose('Clearing metadata');
4795
          $item
4796
            .removeData(metadata.text)
4797
            .removeData(metadata.value)
4798
          ;
4799
          $module
4800
            .removeData(metadata.defaultText)
4801
            .removeData(metadata.defaultValue)
4802
            .removeData(metadata.placeholderText)
4803
          ;
4804
        },
4805
4806
        toggle: function() {
4807
          module.verbose('Toggling menu visibility');
4808
          if( !module.is.active() ) {
4809
            module.show();
4810
          }
4811
          else {
4812
            module.hide();
4813
          }
4814
        },
4815
4816
        show: function(callback) {
4817
          callback = $.isFunction(callback)
4818
            ? callback
4819
            : function(){}
4820
          ;
4821
          if(!module.can.show() && module.is.remote()) {
4822
            module.debug('No API results retrieved, searching before show');
4823
            module.queryRemote(module.get.query(), module.show);
4824
          }
4825
          if( module.can.show() && !module.is.active() ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if module.can.show() && !module.is.active() is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
4826
            module.debug('Showing dropdown');
4827
            if(module.has.message() && !(module.has.maxSelections() || module.has.allResultsFiltered()) ) {
4828
              module.remove.message();
4829
            }
4830
            if(module.is.allFiltered()) {
4831
              return true;
4832
            }
4833
            if(settings.onShow.call(element) !== false) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if settings.onShow.call(element) !== false is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
4834
              module.animate.show(function() {
4835
                if( module.can.click() ) {
4836
                  module.bind.intent();
4837
                }
4838
                if(module.has.menuSearch()) {
4839
                  module.focusSearch();
4840
                }
4841
                module.set.visible();
4842
                callback.call(element);
4843
              });
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
4844
            }
4845
          }
4846
        },
4847
4848
        hide: function(callback) {
4849
          callback = $.isFunction(callback)
4850
            ? callback
4851
            : function(){}
4852
          ;
4853
          if( module.is.active() ) {
4854
            module.debug('Hiding dropdown');
4855
            if(settings.onHide.call(element) !== false) {
4856
              module.animate.hide(function() {
4857
                module.remove.visible();
4858
                callback.call(element);
4859
              });
4860
            }
4861
          }
4862
        },
4863
4864
        hideOthers: function() {
4865
          module.verbose('Finding other dropdowns to hide');
4866
          $allModules
4867
            .not($module)
4868
              .has(selector.menu + '.' + className.visible)
4869
                .dropdown('hide')
4870
          ;
4871
        },
4872
4873
        hideMenu: function() {
4874
          module.verbose('Hiding menu  instantaneously');
4875
          module.remove.active();
4876
          module.remove.visible();
4877
          $menu.transition('hide');
4878
        },
4879
4880
        hideSubMenus: function() {
4881
          var
4882
            $subMenus = $menu.children(selector.item).find(selector.menu)
4883
          ;
4884
          module.verbose('Hiding sub menus', $subMenus);
4885
          $subMenus.transition('hide');
4886
        },
4887
4888
        bind: {
4889
          events: function() {
4890
            if(hasTouch) {
4891
              module.bind.touchEvents();
4892
            }
4893
            module.bind.keyboardEvents();
4894
            module.bind.inputEvents();
4895
            module.bind.mouseEvents();
4896
          },
4897
          touchEvents: function() {
4898
            module.debug('Touch device detected binding additional touch events');
4899
            if( module.is.searchSelection() ) {
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
4900
              // do nothing special yet
4901
            }
4902
            else if( module.is.single() ) {
4903
              $module
4904
                .on('touchstart' + eventNamespace, module.event.test.toggle)
4905
              ;
4906
            }
4907
            $menu
4908
              .on('touchstart' + eventNamespace, selector.item, module.event.item.mouseenter)
4909
            ;
4910
          },
4911
          keyboardEvents: function() {
4912
            module.verbose('Binding keyboard events');
4913
            $module
4914
              .on('keydown' + eventNamespace, module.event.keydown)
4915
            ;
4916
            if( module.has.search() ) {
4917
              $module
4918
                .on(module.get.inputEvent() + eventNamespace, selector.search, module.event.input)
4919
              ;
4920
            }
4921
            if( module.is.multiple() ) {
4922
              $document
4923
                .on('keydown' + elementNamespace, module.event.document.keydown)
4924
              ;
4925
            }
4926
          },
4927
          inputEvents: function() {
4928
            module.verbose('Binding input change events');
4929
            $module
4930
              .on('change' + eventNamespace, selector.input, module.event.change)
4931
            ;
4932
          },
4933
          mouseEvents: function() {
4934
            module.verbose('Binding mouse events');
4935
            if(module.is.multiple()) {
4936
              $module
4937
                .on('click'   + eventNamespace, selector.label,  module.event.label.click)
4938
                .on('click'   + eventNamespace, selector.remove, module.event.remove.click)
4939
              ;
4940
            }
4941
            if( module.is.searchSelection() ) {
4942
              $module
4943
                .on('mousedown' + eventNamespace, module.event.mousedown)
4944
                .on('mouseup'   + eventNamespace, module.event.mouseup)
4945
                .on('mousedown' + eventNamespace, selector.menu,   module.event.menu.mousedown)
4946
                .on('mouseup'   + eventNamespace, selector.menu,   module.event.menu.mouseup)
4947
                .on('click'     + eventNamespace, selector.icon,   module.event.icon.click)
4948
                .on('focus'     + eventNamespace, selector.search, module.event.search.focus)
4949
                .on('click'     + eventNamespace, selector.search, module.event.search.focus)
4950
                .on('blur'      + eventNamespace, selector.search, module.event.search.blur)
4951
                .on('click'     + eventNamespace, selector.text,   module.event.text.focus)
4952
              ;
4953
              if(module.is.multiple()) {
4954
                $module
4955
                  .on('click' + eventNamespace, module.event.click)
4956
                ;
4957
              }
4958
            }
4959
            else {
4960
              if(settings.on == 'click') {
4961
                $module
4962
                  .on('click' + eventNamespace, selector.icon, module.event.icon.click)
4963
                  .on('click' + eventNamespace, module.event.test.toggle)
4964
                ;
4965
              }
4966
              else if(settings.on == 'hover') {
4967
                $module
4968
                  .on('mouseenter' + eventNamespace, module.delay.show)
4969
                  .on('mouseleave' + eventNamespace, module.delay.hide)
4970
                ;
4971
              }
4972
              else {
4973
                $module
4974
                  .on(settings.on + eventNamespace, module.toggle)
4975
                ;
4976
              }
4977
              $module
4978
                .on('mousedown' + eventNamespace, module.event.mousedown)
4979
                .on('mouseup'   + eventNamespace, module.event.mouseup)
4980
                .on('focus'     + eventNamespace, module.event.focus)
4981
              ;
4982
              if(module.has.menuSearch() ) {
4983
                $module
4984
                  .on('blur' + eventNamespace, selector.search, module.event.search.blur)
4985
                ;
4986
              }
4987
              else {
4988
                $module
4989
                  .on('blur' + eventNamespace, module.event.blur)
4990
                ;
4991
              }
4992
            }
4993
            $menu
4994
              .on('mouseenter' + eventNamespace, selector.item, module.event.item.mouseenter)
4995
              .on('mouseleave' + eventNamespace, selector.item, module.event.item.mouseleave)
4996
              .on('click'      + eventNamespace, selector.item, module.event.item.click)
4997
            ;
4998
          },
4999
          intent: function() {
5000
            module.verbose('Binding hide intent event to document');
5001
            if(hasTouch) {
5002
              $document
5003
                .on('touchstart' + elementNamespace, module.event.test.touch)
5004
                .on('touchmove'  + elementNamespace, module.event.test.touch)
5005
              ;
5006
            }
5007
            $document
5008
              .on('click' + elementNamespace, module.event.test.hide)
5009
            ;
5010
          }
5011
        },
5012
5013
        unbind: {
5014
          intent: function() {
5015
            module.verbose('Removing hide intent event from document');
5016
            if(hasTouch) {
5017
              $document
5018
                .off('touchstart' + elementNamespace)
5019
                .off('touchmove' + elementNamespace)
5020
              ;
5021
            }
5022
            $document
5023
              .off('click' + elementNamespace)
5024
            ;
5025
          }
5026
        },
5027
5028
        filter: function(query) {
5029
          var
5030
            searchTerm = (query !== undefined)
5031
              ? query
5032
              : module.get.query(),
5033
            afterFiltered = function() {
5034
              if(module.is.multiple()) {
5035
                module.filterActive();
5036
              }
5037
              if(query || (!query && module.get.activeItem().length == 0)) {
0 ignored issues
show
Best Practice introduced by
Comparing module.get.activeItem().length to 0 using the == operator is not safe. Consider using === instead.
Loading history...
5038
                module.select.firstUnfiltered();
5039
              }
5040
              if( module.has.allResultsFiltered() ) {
5041
                if( settings.onNoResults.call(element, searchTerm) ) {
5042
                  if(settings.allowAdditions) {
5043
                    if(settings.hideAdditions) {
5044
                      module.verbose('User addition with no menu, setting empty style');
5045
                      module.set.empty();
5046
                      module.hideMenu();
5047
                    }
5048
                  }
5049
                  else {
5050
                    module.verbose('All items filtered, showing message', searchTerm);
5051
                    module.add.message(message.noResults);
5052
                  }
5053
                }
5054
                else {
5055
                  module.verbose('All items filtered, hiding dropdown', searchTerm);
5056
                  module.hideMenu();
5057
                }
5058
              }
5059
              else {
5060
                module.remove.empty();
5061
                module.remove.message();
5062
              }
5063
              if(settings.allowAdditions) {
5064
                module.add.userSuggestion(query);
5065
              }
5066
              if(module.is.searchSelection() && module.can.show() && module.is.focusedOnSearch() ) {
5067
                module.show();
5068
              }
5069
            }
5070
          ;
5071
          if(settings.useLabels && module.has.maxSelections()) {
5072
            return;
5073
          }
5074
          if(settings.apiSettings) {
5075
            if( module.can.useAPI() ) {
5076
              module.queryRemote(searchTerm, function() {
5077
                if(settings.filterRemoteData) {
5078
                  module.filterItems(searchTerm);
5079
                }
5080
                afterFiltered();
5081
              });
5082
            }
5083
            else {
5084
              module.error(error.noAPI);
5085
            }
5086
          }
5087
          else {
5088
            module.filterItems(searchTerm);
5089
            afterFiltered();
5090
          }
5091
        },
5092
5093
        queryRemote: function(query, callback) {
5094
          var
5095
            apiSettings = {
5096
              errorDuration : false,
5097
              cache         : 'local',
5098
              throttle      : settings.throttle,
5099
              urlData       : {
5100
                query: query
5101
              },
5102
              onError: function() {
5103
                module.add.message(message.serverError);
5104
                callback();
5105
              },
5106
              onFailure: function() {
5107
                module.add.message(message.serverError);
5108
                callback();
5109
              },
5110
              onSuccess : function(response) {
5111
                module.remove.message();
5112
                module.setup.menu({
5113
                  values: response[fields.remoteValues]
5114
                });
5115
                callback();
5116
              }
5117
            }
5118
          ;
5119
          if( !$module.api('get request') ) {
5120
            module.setup.api();
5121
          }
5122
          apiSettings = $.extend(true, {}, apiSettings, settings.apiSettings);
5123
          $module
5124
            .api('setting', apiSettings)
5125
            .api('query')
5126
          ;
5127
        },
5128
5129
        filterItems: function(query) {
5130
          var
5131
            searchTerm = (query !== undefined)
5132
              ? query
5133
              : module.get.query(),
5134
            results          =  null,
5135
            escapedTerm      = module.escape.string(searchTerm),
5136
            beginsWithRegExp = new RegExp('^' + escapedTerm, 'igm')
5137
          ;
5138
          // avoid loop if we're matching nothing
5139
          if( module.has.query() ) {
5140
            results = [];
5141
5142
            module.verbose('Searching for matching values', searchTerm);
5143
            $item
5144
              .each(function(){
5145
                var
5146
                  $choice = $(this),
5147
                  text,
5148
                  value
5149
                ;
5150
                if(settings.match == 'both' || settings.match == 'text') {
5151
                  text = String(module.get.choiceText($choice, false));
5152
                  if(text.search(beginsWithRegExp) !== -1) {
5153
                    results.push(this);
5154
                    return true;
5155
                  }
5156
                  else if (settings.fullTextSearch === 'exact' && module.exactSearch(searchTerm, text)) {
5157
                    results.push(this);
5158
                    return true;
5159
                  }
5160
                  else if (settings.fullTextSearch === true && module.fuzzySearch(searchTerm, text)) {
5161
                    results.push(this);
5162
                    return true;
5163
                  }
5164
                }
5165
                if(settings.match == 'both' || settings.match == 'value') {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if settings.match == "both"...ttings.match == "value" is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
5166
                  value = String(module.get.choiceValue($choice, text));
0 ignored issues
show
Bug introduced by
The variable text does not seem to be initialized in case settings.match == "both"...ettings.match == "text" on line 5150 is false. Are you sure the function choiceValue handles undefined variables?
Loading history...
5167
                  if(value.search(beginsWithRegExp) !== -1) {
5168
                    results.push(this);
5169
                    return true;
5170
                  }
5171
                  else if (settings.fullTextSearch === 'exact' && module.exactSearch(searchTerm, value)) {
5172
                    results.push(this);
5173
                    return true;
5174
                  }
5175
                  else if (settings.fullTextSearch === true && module.fuzzySearch(searchTerm, value)) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if settings.fullTextSearch ...arch(searchTerm, value) is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
5176
                    results.push(this);
5177
                    return true;
5178
                  }
5179
                }
5180
              })
5181
            ;
5182
          }
5183
          module.debug('Showing only matched items', searchTerm);
5184
          module.remove.filteredItem();
5185
          if(results) {
5186
            $item
5187
              .not(results)
5188
              .addClass(className.filtered)
5189
            ;
5190
          }
5191
        },
5192
5193
        fuzzySearch: function(query, term) {
5194
          var
5195
            termLength  = term.length,
5196
            queryLength = query.length
5197
          ;
5198
          query = query.toLowerCase();
5199
          term  = term.toLowerCase();
5200
          if(queryLength > termLength) {
5201
            return false;
5202
          }
5203
          if(queryLength === termLength) {
5204
            return (query === term);
5205
          }
5206
          search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
5207
            var
5208
              queryCharacter = query.charCodeAt(characterIndex)
5209
            ;
5210
            while(nextCharacterIndex < termLength) {
5211
              if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
5212
                continue search;
5213
              }
5214
            }
5215
            return false;
5216
          }
5217
          return true;
5218
        },
5219
        exactSearch: function (query, term) {
5220
          query = query.toLowerCase();
5221
          term  = term.toLowerCase();
5222
          if(term.indexOf(query) > -1) {
5223
             return true;
5224
          }
5225
          return false;
5226
        },
5227
        filterActive: function() {
5228
          if(settings.useLabels) {
5229
            $item.filter('.' + className.active)
5230
              .addClass(className.filtered)
5231
            ;
5232
          }
5233
        },
5234
5235
        focusSearch: function(skipHandler) {
5236
          if( module.has.search() && !module.is.focusedOnSearch() ) {
5237
            if(skipHandler) {
5238
              $module.off('focus' + eventNamespace, selector.search);
5239
              $search.focus();
5240
              $module.on('focus'  + eventNamespace, selector.search, module.event.search.focus);
5241
            }
5242
            else {
5243
              $search.focus();
5244
            }
5245
          }
5246
        },
5247
5248
        forceSelection: function() {
5249
          var
5250
            $currentlySelected = $item.not(className.filtered).filter('.' + className.selected).eq(0),
5251
            $activeItem        = $item.not(className.filtered).filter('.' + className.active).eq(0),
5252
            $selectedItem      = ($currentlySelected.length > 0)
5253
              ? $currentlySelected
5254
              : $activeItem,
5255
            hasSelected = ($selectedItem.length > 0)
5256
          ;
5257
          if(hasSelected && !module.is.multiple()) {
5258
            module.debug('Forcing partial selection to selected item', $selectedItem);
5259
            module.event.item.click.call($selectedItem, {}, true);
5260
            return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
5261
          }
5262
          else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
5263
            if(settings.allowAdditions) {
5264
              module.set.selected(module.get.query());
5265
              module.remove.searchTerm();
5266
            }
5267
            else {
5268
              module.remove.searchTerm();
5269
            }
5270
          }
5271
        },
5272
5273
        event: {
5274
          change: function() {
5275
            if(!internalChange) {
5276
              module.debug('Input changed, updating selection');
5277
              module.set.selected();
5278
            }
5279
          },
5280
          focus: function() {
5281
            if(settings.showOnFocus && !activated && module.is.hidden() && !pageLostFocus) {
5282
              module.show();
5283
            }
5284
          },
5285
          blur: function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
5286
            pageLostFocus = (document.activeElement === this);
5287
            if(!activated && !pageLostFocus) {
5288
              module.remove.activeLabel();
5289
              module.hide();
5290
            }
5291
          },
5292
          mousedown: function() {
5293
            if(module.is.searchSelection()) {
5294
              // prevent menu hiding on immediate re-focus
5295
              willRefocus = true;
5296
            }
5297
            else {
5298
              // prevents focus callback from occurring on mousedown
5299
              activated = true;
5300
            }
5301
          },
5302
          mouseup: function() {
5303
            if(module.is.searchSelection()) {
5304
              // prevent menu hiding on immediate re-focus
5305
              willRefocus = false;
5306
            }
5307
            else {
5308
              activated = false;
5309
            }
5310
          },
5311
          click: function(event) {
5312
            var
5313
              $target = $(event.target)
5314
            ;
5315
            // focus search
5316
            if($target.is($module)) {
5317
              if(!module.is.focusedOnSearch()) {
5318
                module.focusSearch();
5319
              }
5320
              else {
5321
                module.show();
5322
              }
5323
            }
5324
          },
5325
          search: {
5326
            focus: function() {
5327
              activated = true;
5328
              if(module.is.multiple()) {
5329
                module.remove.activeLabel();
5330
              }
5331
              if(settings.showOnFocus) {
5332
                module.search();
5333
              }
5334
            },
5335
            blur: function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
5336
              pageLostFocus = (document.activeElement === this);
5337
              if(module.is.searchSelection() && !willRefocus) {
5338
                if(!itemActivated && !pageLostFocus) {
5339
                  if(settings.forceSelection) {
5340
                    module.forceSelection();
5341
                  }
5342
                  module.hide();
5343
                }
5344
              }
5345
              willRefocus = false;
5346
            }
5347
          },
5348
          icon: {
5349
            click: function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
5350
              module.toggle();
5351
            }
5352
          },
5353
          text: {
5354
            focus: function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
5355
              activated = true;
5356
              module.focusSearch();
5357
            }
5358
          },
5359
          input: function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
5360
            if(module.is.multiple() || module.is.searchSelection()) {
5361
              module.set.filtered();
5362
            }
5363
            clearTimeout(module.timer);
5364
            module.timer = setTimeout(module.search, settings.delay.search);
5365
          },
5366
          label: {
5367
            click: function(event) {
5368
              var
5369
                $label        = $(this),
5370
                $labels       = $module.find(selector.label),
5371
                $activeLabels = $labels.filter('.' + className.active),
5372
                $nextActive   = $label.nextAll('.' + className.active),
5373
                $prevActive   = $label.prevAll('.' + className.active),
5374
                $range = ($nextActive.length > 0)
5375
                  ? $label.nextUntil($nextActive).add($activeLabels).add($label)
5376
                  : $label.prevUntil($prevActive).add($activeLabels).add($label)
5377
              ;
5378
              if(event.shiftKey) {
5379
                $activeLabels.removeClass(className.active);
5380
                $range.addClass(className.active);
5381
              }
5382
              else if(event.ctrlKey) {
5383
                $label.toggleClass(className.active);
5384
              }
5385
              else {
5386
                $activeLabels.removeClass(className.active);
5387
                $label.addClass(className.active);
5388
              }
5389
              settings.onLabelSelect.apply(this, $labels.filter('.' + className.active));
5390
            }
5391
          },
5392
          remove: {
5393
            click: function() {
5394
              var
5395
                $label = $(this).parent()
5396
              ;
5397
              if( $label.hasClass(className.active) ) {
5398
                // remove all selected labels
5399
                module.remove.activeLabels();
5400
              }
5401
              else {
5402
                // remove this label only
5403
                module.remove.activeLabels( $label );
5404
              }
5405
            }
5406
          },
5407
          test: {
5408
            toggle: function(event) {
5409
              var
5410
                toggleBehavior = (module.is.multiple())
5411
                  ? module.show
5412
                  : module.toggle
5413
              ;
5414
              if(module.is.bubbledLabelClick(event) || module.is.bubbledIconClick(event)) {
5415
                return;
5416
              }
5417
              if( module.determine.eventOnElement(event, toggleBehavior) ) {
5418
                event.preventDefault();
5419
              }
5420
            },
5421
            touch: function(event) {
5422
              module.determine.eventOnElement(event, function() {
5423
                if(event.type == 'touchstart') {
5424
                  module.timer = setTimeout(function() {
5425
                    module.hide();
5426
                  }, settings.delay.touch);
5427
                }
5428
                else if(event.type == 'touchmove') {
5429
                  clearTimeout(module.timer);
5430
                }
5431
              });
5432
              event.stopPropagation();
5433
            },
5434
            hide: function(event) {
5435
              module.determine.eventInModule(event, module.hide);
5436
            }
5437
          },
5438
          select: {
5439
            mutation: function(mutations) {
0 ignored issues
show
Unused Code introduced by
The parameter mutations is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
5440
              module.debug('<select> modified, recreating menu');
5441
              module.setup.select();
5442
            }
5443
          },
5444
          menu: {
5445
            mutation: function(mutations) {
5446
              var
5447
                mutation   = mutations[0],
5448
                $addedNode = mutation.addedNodes
5449
                  ? $(mutation.addedNodes[0])
5450
                  : $(false),
5451
                $removedNode = mutation.removedNodes
5452
                  ? $(mutation.removedNodes[0])
5453
                  : $(false),
5454
                $changedNodes  = $addedNode.add($removedNode),
5455
                isUserAddition = $changedNodes.is(selector.addition) || $changedNodes.closest(selector.addition).length > 0,
5456
                isMessage      = $changedNodes.is(selector.message)  || $changedNodes.closest(selector.message).length > 0
5457
              ;
5458
              if(isUserAddition || isMessage) {
5459
                module.debug('Updating item selector cache');
5460
                module.refreshItems();
5461
              }
5462
              else {
5463
                module.debug('Menu modified, updating selector cache');
5464
                module.refresh();
5465
              }
5466
            },
5467
            mousedown: function() {
5468
              itemActivated = true;
5469
            },
5470
            mouseup: function() {
5471
              itemActivated = false;
5472
            }
5473
          },
5474
          item: {
5475
            mouseenter: function(event) {
5476
              var
5477
                $target        = $(event.target),
5478
                $item          = $(this),
5479
                $subMenu       = $item.children(selector.menu),
5480
                $otherMenus    = $item.siblings(selector.item).children(selector.menu),
5481
                hasSubMenu     = ($subMenu.length > 0),
5482
                isBubbledEvent = ($subMenu.find($target).length > 0)
5483
              ;
5484
              if( !isBubbledEvent && hasSubMenu ) {
5485
                clearTimeout(module.itemTimer);
5486
                module.itemTimer = setTimeout(function() {
5487
                  module.verbose('Showing sub-menu', $subMenu);
5488
                  $.each($otherMenus, function() {
5489
                    module.animate.hide(false, $(this));
5490
                  });
5491
                  module.animate.show(false, $subMenu);
5492
                }, settings.delay.show);
5493
                event.preventDefault();
5494
              }
5495
            },
5496
            mouseleave: function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
5497
              var
5498
                $subMenu = $(this).children(selector.menu)
5499
              ;
5500
              if($subMenu.length > 0) {
5501
                clearTimeout(module.itemTimer);
5502
                module.itemTimer = setTimeout(function() {
5503
                  module.verbose('Hiding sub-menu', $subMenu);
5504
                  module.animate.hide(false, $subMenu);
5505
                }, settings.delay.hide);
5506
              }
5507
            },
5508
            click: function (event, skipRefocus) {
5509
              var
5510
                $choice        = $(this),
5511
                $target        = (event)
5512
                  ? $(event.target)
5513
                  : $(''),
5514
                $subMenu       = $choice.find(selector.menu),
5515
                text           = module.get.choiceText($choice),
5516
                value          = module.get.choiceValue($choice, text),
5517
                hasSubMenu     = ($subMenu.length > 0),
5518
                isBubbledEvent = ($subMenu.find($target).length > 0)
5519
              ;
5520
              // prevents IE11 bug where menu receives focus even though `tabindex=-1`
5521
              if(module.has.menuSearch()) {
5522
                $(document.activeElement).blur();
5523
              }
5524
              if(!isBubbledEvent && (!hasSubMenu || settings.allowCategorySelection)) {
5525
                if(module.is.searchSelection()) {
5526
                  if(settings.allowAdditions) {
5527
                    module.remove.userAddition();
5528
                  }
5529
                  module.remove.searchTerm();
5530
                  if(!module.is.focusedOnSearch() && !(skipRefocus == true)) {
0 ignored issues
show
Best Practice introduced by
Comparing skipRefocus to true using the == operator is not safe. Consider using === instead.
Loading history...
5531
                    module.focusSearch(true);
5532
                  }
5533
                }
5534
                if(!settings.useLabels) {
5535
                  module.remove.filteredItem();
5536
                  module.set.scrollPosition($choice);
5537
                }
5538
                module.determine.selectAction.call(this, text, value);
5539
              }
5540
            }
5541
          },
5542
5543
          document: {
5544
            // label selection should occur even when element has no focus
5545
            keydown: function(event) {
5546
              var
5547
                pressedKey    = event.which,
5548
                isShortcutKey = module.is.inObject(pressedKey, keys)
5549
              ;
5550
              if(isShortcutKey) {
5551
                var
5552
                  $label            = $module.find(selector.label),
5553
                  $activeLabel      = $label.filter('.' + className.active),
5554
                  activeValue       = $activeLabel.data(metadata.value),
0 ignored issues
show
Unused Code introduced by
The variable activeValue seems to be never used. Consider removing it.
Loading history...
5555
                  labelIndex        = $label.index($activeLabel),
5556
                  labelCount        = $label.length,
5557
                  hasActiveLabel    = ($activeLabel.length > 0),
5558
                  hasMultipleActive = ($activeLabel.length > 1),
5559
                  isFirstLabel      = (labelIndex === 0),
5560
                  isLastLabel       = (labelIndex + 1 == labelCount),
5561
                  isSearch          = module.is.searchSelection(),
5562
                  isFocusedOnSearch = module.is.focusedOnSearch(),
5563
                  isFocused         = module.is.focused(),
5564
                  caretAtStart      = (isFocusedOnSearch && module.get.caretPosition() === 0),
5565
                  $nextLabel
0 ignored issues
show
Unused Code introduced by
The variable $nextLabel seems to be never used. Consider removing it.
Loading history...
5566
                ;
5567
                if(isSearch && !hasActiveLabel && !isFocusedOnSearch) {
5568
                  return;
5569
                }
5570
5571
                if(pressedKey == keys.leftArrow) {
5572
                  // activate previous label
5573
                  if((isFocused || caretAtStart) && !hasActiveLabel) {
5574
                    module.verbose('Selecting previous label');
5575
                    $label.last().addClass(className.active);
5576
                  }
5577
                  else if(hasActiveLabel) {
5578
                    if(!event.shiftKey) {
5579
                      module.verbose('Selecting previous label');
5580
                      $label.removeClass(className.active);
5581
                    }
5582
                    else {
5583
                      module.verbose('Adding previous label to selection');
5584
                    }
5585
                    if(isFirstLabel && !hasMultipleActive) {
5586
                      $activeLabel.addClass(className.active);
5587
                    }
5588
                    else {
5589
                      $activeLabel.prev(selector.siblingLabel)
5590
                        .addClass(className.active)
5591
                        .end()
5592
                      ;
5593
                    }
5594
                    event.preventDefault();
5595
                  }
5596
                }
5597
                else if(pressedKey == keys.rightArrow) {
5598
                  // activate first label
5599
                  if(isFocused && !hasActiveLabel) {
5600
                    $label.first().addClass(className.active);
5601
                  }
5602
                  // activate next label
5603
                  if(hasActiveLabel) {
5604
                    if(!event.shiftKey) {
5605
                      module.verbose('Selecting next label');
5606
                      $label.removeClass(className.active);
5607
                    }
5608
                    else {
5609
                      module.verbose('Adding next label to selection');
5610
                    }
5611
                    if(isLastLabel) {
5612
                      if(isSearch) {
5613
                        if(!isFocusedOnSearch) {
5614
                          module.focusSearch();
5615
                        }
5616
                        else {
5617
                          $label.removeClass(className.active);
5618
                        }
5619
                      }
5620
                      else if(hasMultipleActive) {
5621
                        $activeLabel.next(selector.siblingLabel).addClass(className.active);
5622
                      }
5623
                      else {
5624
                        $activeLabel.addClass(className.active);
5625
                      }
5626
                    }
5627
                    else {
5628
                      $activeLabel.next(selector.siblingLabel).addClass(className.active);
5629
                    }
5630
                    event.preventDefault();
5631
                  }
5632
                }
5633
                else if(pressedKey == keys.deleteKey || pressedKey == keys.backspace) {
5634
                  if(hasActiveLabel) {
5635
                    module.verbose('Removing active labels');
5636
                    if(isLastLabel) {
5637
                      if(isSearch && !isFocusedOnSearch) {
5638
                        module.focusSearch();
5639
                      }
5640
                    }
5641
                    $activeLabel.last().next(selector.siblingLabel).addClass(className.active);
5642
                    module.remove.activeLabels($activeLabel);
5643
                    event.preventDefault();
5644
                  }
5645
                  else if(caretAtStart && !hasActiveLabel && pressedKey == keys.backspace) {
5646
                    module.verbose('Removing last label on input backspace');
5647
                    $activeLabel = $label.last().addClass(className.active);
5648
                    module.remove.activeLabels($activeLabel);
5649
                  }
5650
                }
5651
                else {
5652
                  $activeLabel.removeClass(className.active);
5653
                }
5654
              }
5655
            }
5656
          },
5657
5658
          keydown: function(event) {
5659
            var
5660
              pressedKey    = event.which,
5661
              isShortcutKey = module.is.inObject(pressedKey, keys)
5662
            ;
5663
            if(isShortcutKey) {
5664
              var
5665
                $currentlySelected = $item.not(selector.unselectable).filter('.' + className.selected).eq(0),
5666
                $activeItem        = $menu.children('.' + className.active).eq(0),
5667
                $selectedItem      = ($currentlySelected.length > 0)
5668
                  ? $currentlySelected
5669
                  : $activeItem,
5670
                $visibleItems = ($selectedItem.length > 0)
5671
                  ? $selectedItem.siblings(':not(.' + className.filtered +')').addBack()
5672
                  : $menu.children(':not(.' + className.filtered +')'),
5673
                $subMenu              = $selectedItem.children(selector.menu),
5674
                $parentMenu           = $selectedItem.closest(selector.menu),
5675
                inVisibleMenu         = ($parentMenu.hasClass(className.visible) || $parentMenu.hasClass(className.animating) || $parentMenu.parent(selector.menu).length > 0),
5676
                hasSubMenu            = ($subMenu.length> 0),
5677
                hasSelectedItem       = ($selectedItem.length > 0),
5678
                selectedIsSelectable  = ($selectedItem.not(selector.unselectable).length > 0),
5679
                delimiterPressed      = (pressedKey == keys.delimiter && settings.allowAdditions && module.is.multiple()),
5680
                isAdditionWithoutMenu = (settings.allowAdditions && settings.hideAdditions && (pressedKey == keys.enter || delimiterPressed) && selectedIsSelectable),
5681
                $nextItem,
5682
                isSubMenuItem,
5683
                newIndex
0 ignored issues
show
Unused Code introduced by
The variable newIndex seems to be never used. Consider removing it.
Loading history...
5684
              ;
5685
              // allow selection with menu closed
5686
              if(isAdditionWithoutMenu) {
5687
                module.verbose('Selecting item from keyboard shortcut', $selectedItem);
5688
                module.event.item.click.call($selectedItem, event);
5689
                if(module.is.searchSelection()) {
5690
                  module.remove.searchTerm();
5691
                }
5692
              }
5693
5694
              // visible menu keyboard shortcuts
5695
              if( module.is.visible() ) {
5696
5697
                // enter (select or open sub-menu)
5698
                if(pressedKey == keys.enter || delimiterPressed) {
5699
                  if(pressedKey == keys.enter && hasSelectedItem && hasSubMenu && !settings.allowCategorySelection) {
5700
                    module.verbose('Pressed enter on unselectable category, opening sub menu');
5701
                    pressedKey = keys.rightArrow;
5702
                  }
5703
                  else if(selectedIsSelectable) {
5704
                    module.verbose('Selecting item from keyboard shortcut', $selectedItem);
5705
                    module.event.item.click.call($selectedItem, event);
5706
                    if(module.is.searchSelection()) {
5707
                      module.remove.searchTerm();
5708
                    }
5709
                  }
5710
                  event.preventDefault();
5711
                }
5712
5713
                // sub-menu actions
5714
                if(hasSelectedItem) {
5715
5716
                  if(pressedKey == keys.leftArrow) {
5717
5718
                    isSubMenuItem = ($parentMenu[0] !== $menu[0]);
5719
5720
                    if(isSubMenuItem) {
5721
                      module.verbose('Left key pressed, closing sub-menu');
5722
                      module.animate.hide(false, $parentMenu);
5723
                      $selectedItem
5724
                        .removeClass(className.selected)
5725
                      ;
5726
                      $parentMenu
5727
                        .closest(selector.item)
5728
                          .addClass(className.selected)
5729
                      ;
5730
                      event.preventDefault();
5731
                    }
5732
                  }
5733
5734
                  // right arrow (show sub-menu)
5735
                  if(pressedKey == keys.rightArrow) {
5736
                    if(hasSubMenu) {
5737
                      module.verbose('Right key pressed, opening sub-menu');
5738
                      module.animate.show(false, $subMenu);
5739
                      $selectedItem
5740
                        .removeClass(className.selected)
5741
                      ;
5742
                      $subMenu
5743
                        .find(selector.item).eq(0)
5744
                          .addClass(className.selected)
5745
                      ;
5746
                      event.preventDefault();
5747
                    }
5748
                  }
5749
                }
5750
5751
                // up arrow (traverse menu up)
5752
                if(pressedKey == keys.upArrow) {
5753
                  $nextItem = (hasSelectedItem && inVisibleMenu)
5754
                    ? $selectedItem.prevAll(selector.item + ':not(' + selector.unselectable + ')').eq(0)
5755
                    : $item.eq(0)
5756
                  ;
5757
                  if($visibleItems.index( $nextItem ) < 0) {
5758
                    module.verbose('Up key pressed but reached top of current menu');
5759
                    event.preventDefault();
5760
                    return;
5761
                  }
5762
                  else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
5763
                    module.verbose('Up key pressed, changing active item');
5764
                    $selectedItem
5765
                      .removeClass(className.selected)
5766
                    ;
5767
                    $nextItem
5768
                      .addClass(className.selected)
5769
                    ;
5770
                    module.set.scrollPosition($nextItem);
5771
                    if(settings.selectOnKeydown && module.is.single()) {
5772
                      module.set.selectedItem($nextItem);
5773
                    }
5774
                  }
5775
                  event.preventDefault();
5776
                }
5777
5778
                // down arrow (traverse menu down)
5779
                if(pressedKey == keys.downArrow) {
5780
                  $nextItem = (hasSelectedItem && inVisibleMenu)
5781
                    ? $nextItem = $selectedItem.nextAll(selector.item + ':not(' + selector.unselectable + ')').eq(0)
0 ignored issues
show
Unused Code introduced by
The assignment to variable $nextItem seems to be never used. Consider removing it.
Loading history...
5782
                    : $item.eq(0)
5783
                  ;
5784
                  if($nextItem.length === 0) {
5785
                    module.verbose('Down key pressed but reached bottom of current menu');
5786
                    event.preventDefault();
5787
                    return;
5788
                  }
5789
                  else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
5790
                    module.verbose('Down key pressed, changing active item');
5791
                    $item
5792
                      .removeClass(className.selected)
5793
                    ;
5794
                    $nextItem
5795
                      .addClass(className.selected)
5796
                    ;
5797
                    module.set.scrollPosition($nextItem);
5798
                    if(settings.selectOnKeydown && module.is.single()) {
5799
                      module.set.selectedItem($nextItem);
5800
                    }
5801
                  }
5802
                  event.preventDefault();
5803
                }
5804
5805
                // page down (show next page)
5806
                if(pressedKey == keys.pageUp) {
5807
                  module.scrollPage('up');
5808
                  event.preventDefault();
5809
                }
5810
                if(pressedKey == keys.pageDown) {
5811
                  module.scrollPage('down');
5812
                  event.preventDefault();
5813
                }
5814
5815
                // escape (close menu)
5816
                if(pressedKey == keys.escape) {
5817
                  module.verbose('Escape key pressed, closing dropdown');
5818
                  module.hide();
5819
                }
5820
5821
              }
5822
              else {
5823
                // delimiter key
5824
                if(delimiterPressed) {
5825
                  event.preventDefault();
5826
                }
5827
                // down arrow (open menu)
5828
                if(pressedKey == keys.downArrow && !module.is.visible()) {
5829
                  module.verbose('Down key pressed, showing dropdown');
5830
                  module.show();
5831
                  event.preventDefault();
5832
                }
5833
              }
5834
            }
5835
            else {
5836
              if( !module.has.search() ) {
5837
                module.set.selectedLetter( String.fromCharCode(pressedKey) );
5838
              }
5839
            }
5840
          }
5841
        },
5842
5843
        trigger: {
5844
          change: function() {
5845
            var
5846
              events       = document.createEvent('HTMLEvents'),
5847
              inputElement = $input[0]
5848
            ;
5849
            if(inputElement) {
5850
              module.verbose('Triggering native change event');
5851
              events.initEvent('change', true, false);
5852
              inputElement.dispatchEvent(events);
5853
            }
5854
          }
5855
        },
5856
5857
        determine: {
5858
          selectAction: function(text, value) {
5859
            module.verbose('Determining action', settings.action);
5860
            if( $.isFunction( module.action[settings.action] ) ) {
5861
              module.verbose('Triggering preset action', settings.action, text, value);
5862
              module.action[ settings.action ].call(element, text, value, this);
5863
            }
5864
            else if( $.isFunction(settings.action) ) {
5865
              module.verbose('Triggering user action', settings.action, text, value);
5866
              settings.action.call(element, text, value, this);
5867
            }
5868
            else {
5869
              module.error(error.action, settings.action);
5870
            }
5871
          },
5872
          eventInModule: function(event, callback) {
5873
            var
5874
              $target    = $(event.target),
5875
              inDocument = ($target.closest(document.documentElement).length > 0),
5876
              inModule   = ($target.closest($module).length > 0)
5877
            ;
5878
            callback = $.isFunction(callback)
5879
              ? callback
5880
              : function(){}
5881
            ;
5882
            if(inDocument && !inModule) {
5883
              module.verbose('Triggering event', callback);
5884
              callback();
5885
              return true;
5886
            }
5887
            else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
5888
              module.verbose('Event occurred in dropdown, canceling callback');
5889
              return false;
5890
            }
5891
          },
5892
          eventOnElement: function(event, callback) {
5893
            var
5894
              $target      = $(event.target),
5895
              $label       = $target.closest(selector.siblingLabel),
5896
              inVisibleDOM = document.body.contains(event.target),
5897
              notOnLabel   = ($module.find($label).length === 0),
5898
              notInMenu    = ($target.closest($menu).length === 0)
5899
            ;
5900
            callback = $.isFunction(callback)
5901
              ? callback
5902
              : function(){}
5903
            ;
5904
            if(inVisibleDOM && notOnLabel && notInMenu) {
5905
              module.verbose('Triggering event', callback);
5906
              callback();
5907
              return true;
5908
            }
5909
            else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
5910
              module.verbose('Event occurred in dropdown menu, canceling callback');
5911
              return false;
5912
            }
5913
          }
5914
        },
5915
5916
        action: {
5917
5918
          nothing: function() {},
5919
5920
          activate: function(text, value, element) {
5921
            value = (value !== undefined)
5922
              ? value
5923
              : text
5924
            ;
5925
            if( module.can.activate( $(element) ) ) {
5926
              module.set.selected(value, $(element));
5927
              if(module.is.multiple() && !module.is.allFiltered()) {
5928
                return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
5929
              }
5930
              else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
5931
                module.hideAndClear();
5932
              }
5933
            }
5934
          },
5935
5936
          select: function(text, value, element) {
5937
            value = (value !== undefined)
5938
              ? value
5939
              : text
5940
            ;
5941
            if( module.can.activate( $(element) ) ) {
5942
              module.set.value(value, $(element));
5943
              if(module.is.multiple() && !module.is.allFiltered()) {
5944
                return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
5945
              }
5946
              else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
5947
                module.hideAndClear();
5948
              }
5949
            }
5950
          },
5951
5952
          combo: function(text, value, element) {
5953
            value = (value !== undefined)
5954
              ? value
5955
              : text
5956
            ;
5957
            module.set.selected(value, $(element));
5958
            module.hideAndClear();
5959
          },
5960
5961
          hide: function(text, value, element) {
0 ignored issues
show
Unused Code introduced by
The parameter element is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
5962
            module.set.value(value, text);
5963
            module.hideAndClear();
5964
          }
5965
5966
        },
5967
5968
        get: {
5969
          id: function() {
5970
            return id;
5971
          },
5972
          defaultText: function() {
5973
            return $module.data(metadata.defaultText);
5974
          },
5975
          defaultValue: function() {
5976
            return $module.data(metadata.defaultValue);
5977
          },
5978
          placeholderText: function() {
5979
            return $module.data(metadata.placeholderText) || '';
5980
          },
5981
          text: function() {
5982
            return $text.text();
5983
          },
5984
          query: function() {
5985
            return $.trim($search.val());
5986
          },
5987
          searchWidth: function(value) {
5988
            value = (value !== undefined)
5989
              ? value
5990
              : $search.val()
5991
            ;
5992
            $sizer.text(value);
5993
            // prevent rounding issues
5994
            return Math.ceil( $sizer.width() + 1);
5995
          },
5996
          selectionCount: function() {
5997
            var
5998
              values = module.get.values(),
5999
              count
6000
            ;
6001
            count = ( module.is.multiple() )
6002
              ? $.isArray(values)
6003
                ? values.length
6004
                : 0
6005
              : (module.get.value() !== '')
6006
                ? 1
6007
                : 0
6008
            ;
6009
            return count;
6010
          },
6011
          transition: function($subMenu) {
6012
            return (settings.transition == 'auto')
6013
              ? module.is.upward($subMenu)
6014
                ? 'slide up'
6015
                : 'slide down'
6016
              : settings.transition
6017
            ;
6018
          },
6019
          userValues: function() {
6020
            var
6021
              values = module.get.values()
6022
            ;
6023
            if(!values) {
6024
              return false;
6025
            }
6026
            values = $.isArray(values)
6027
              ? values
6028
              : [values]
6029
            ;
6030
            return $.grep(values, function(value) {
6031
              return (module.get.item(value) === false);
6032
            });
6033
          },
6034
          uniqueArray: function(array) {
6035
            return $.grep(array, function (value, index) {
6036
                return $.inArray(value, array) === index;
6037
            });
6038
          },
6039
          caretPosition: function() {
6040
            var
6041
              input = $search.get(0),
6042
              range,
6043
              rangeLength
6044
            ;
6045
            if('selectionStart' in input) {
6046
              return input.selectionStart;
6047
            }
6048
            else if (document.selection) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if document.selection is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
6049
              input.focus();
6050
              range       = document.selection.createRange();
6051
              rangeLength = range.text.length;
6052
              range.moveStart('character', -input.value.length);
6053
              return range.text.length - rangeLength;
6054
            }
6055
          },
6056
          value: function() {
6057
            var
6058
              value = ($input.length > 0)
6059
                ? $input.val()
6060
                : $module.data(metadata.value),
6061
              isEmptyMultiselect = ($.isArray(value) && value.length === 1 && value[0] === '')
6062
            ;
6063
            // prevents placeholder element from being selected when multiple
6064
            return (value === undefined || isEmptyMultiselect)
6065
              ? ''
6066
              : value
6067
            ;
6068
          },
6069
          values: function() {
6070
            var
6071
              value = module.get.value()
6072
            ;
6073
            if(value === '') {
6074
              return '';
6075
            }
6076
            return ( !module.has.selectInput() && module.is.multiple() )
6077
              ? (typeof value == 'string') // delimited string
6078
                ? value.split(settings.delimiter)
6079
                : ''
6080
              : value
6081
            ;
6082
          },
6083
          remoteValues: function() {
6084
            var
6085
              values = module.get.values(),
6086
              remoteValues = false
6087
            ;
6088
            if(values) {
6089
              if(typeof values == 'string') {
6090
                values = [values];
6091
              }
6092
              $.each(values, function(index, value) {
6093
                var
6094
                  name = module.read.remoteData(value)
6095
                ;
6096
                module.verbose('Restoring value from session data', name, value);
6097
                if(name) {
6098
                  if(!remoteValues) {
6099
                    remoteValues = {};
6100
                  }
6101
                  remoteValues[value] = name;
6102
                }
6103
              });
6104
            }
6105
            return remoteValues;
6106
          },
6107
          choiceText: function($choice, preserveHTML) {
6108
            preserveHTML = (preserveHTML !== undefined)
6109
              ? preserveHTML
6110
              : settings.preserveHTML
6111
            ;
6112
            if($choice) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if $choice is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
6113
              if($choice.find(selector.menu).length > 0) {
6114
                module.verbose('Retrieving text of element with sub-menu');
6115
                $choice = $choice.clone();
6116
                $choice.find(selector.menu).remove();
6117
                $choice.find(selector.menuIcon).remove();
6118
              }
6119
              return ($choice.data(metadata.text) !== undefined)
6120
                ? $choice.data(metadata.text)
6121
                : (preserveHTML)
6122
                  ? $.trim($choice.html())
6123
                  : $.trim($choice.text())
6124
              ;
6125
            }
6126
          },
6127
          choiceValue: function($choice, choiceText) {
6128
            choiceText = choiceText || module.get.choiceText($choice);
6129
            if(!$choice) {
6130
              return false;
6131
            }
6132
            return ($choice.data(metadata.value) !== undefined)
6133
              ? String( $choice.data(metadata.value) )
6134
              : (typeof choiceText === 'string')
6135
                ? $.trim(choiceText.toLowerCase())
6136
                : String(choiceText)
6137
            ;
6138
          },
6139
          inputEvent: function() {
6140
            var
6141
              input = $search[0]
6142
            ;
6143
            if(input) {
6144
              return (input.oninput !== undefined)
6145
                ? 'input'
6146
                : (input.onpropertychange !== undefined)
6147
                  ? 'propertychange'
6148
                  : 'keyup'
6149
              ;
6150
            }
6151
            return false;
6152
          },
6153
          selectValues: function() {
6154
            var
6155
              select = {}
6156
            ;
6157
            select.values = [];
6158
            $module
6159
              .find('option')
6160
                .each(function() {
6161
                  var
6162
                    $option  = $(this),
6163
                    name     = $option.html(),
6164
                    disabled = $option.attr('disabled'),
6165
                    value    = ( $option.attr('value') !== undefined )
6166
                      ? $option.attr('value')
6167
                      : name
6168
                  ;
6169
                  if(settings.placeholder === 'auto' && value === '') {
6170
                    select.placeholder = name;
6171
                  }
6172
                  else {
6173
                    select.values.push({
6174
                      name     : name,
6175
                      value    : value,
6176
                      disabled : disabled
6177
                    });
6178
                  }
6179
                })
6180
            ;
6181
            if(settings.placeholder && settings.placeholder !== 'auto') {
6182
              module.debug('Setting placeholder value to', settings.placeholder);
6183
              select.placeholder = settings.placeholder;
6184
            }
6185
            if(settings.sortSelect) {
6186
              select.values.sort(function(a, b) {
6187
                return (a.name > b.name)
6188
                  ? 1
6189
                  : -1
6190
                ;
6191
              });
6192
              module.debug('Retrieved and sorted values from select', select);
6193
            }
6194
            else {
6195
              module.debug('Retrieved values from select', select);
6196
            }
6197
            return select;
6198
          },
6199
          activeItem: function() {
6200
            return $item.filter('.'  + className.active);
6201
          },
6202
          selectedItem: function() {
6203
            var
6204
              $selectedItem = $item.not(selector.unselectable).filter('.'  + className.selected)
6205
            ;
6206
            return ($selectedItem.length > 0)
6207
              ? $selectedItem
6208
              : $item.eq(0)
6209
            ;
6210
          },
6211
          itemWithAdditions: function(value) {
6212
            var
6213
              $items       = module.get.item(value),
6214
              $userItems   = module.create.userChoice(value),
6215
              hasUserItems = ($userItems && $userItems.length > 0)
6216
            ;
6217
            if(hasUserItems) {
6218
              $items = ($items.length > 0)
6219
                ? $items.add($userItems)
6220
                : $userItems
6221
              ;
6222
            }
6223
            return $items;
6224
          },
6225
          item: function(value, strict) {
6226
            var
6227
              $selectedItem = false,
6228
              shouldSearch,
6229
              isMultiple
6230
            ;
6231
            value = (value !== undefined)
6232
              ? value
6233
              : ( module.get.values() !== undefined)
6234
                ? module.get.values()
6235
                : module.get.text()
6236
            ;
6237
            shouldSearch = (isMultiple)
0 ignored issues
show
Bug introduced by
The variable isMultiple seems to be never initialized.
Loading history...
6238
              ? (value.length > 0)
6239
              : (value !== undefined && value !== null)
6240
            ;
6241
            isMultiple = (module.is.multiple() && $.isArray(value));
6242
            strict     = (value === '' || value === 0)
6243
              ? true
6244
              : strict || false
6245
            ;
6246
            if(shouldSearch) {
6247
              $item
6248
                .each(function() {
6249
                  var
6250
                    $choice       = $(this),
6251
                    optionText    = module.get.choiceText($choice),
6252
                    optionValue   = module.get.choiceValue($choice, optionText)
6253
                  ;
6254
                  // safe early exit
6255
                  if(optionValue === null || optionValue === undefined) {
6256
                    return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
6257
                  }
6258
                  if(isMultiple) {
6259
                    if($.inArray( String(optionValue), value) !== -1 || $.inArray(optionText, value) !== -1) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if $.inArray(String(optionV...tionText, value) !== -1 is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
6260
                      $selectedItem = ($selectedItem)
6261
                        ? $selectedItem.add($choice)
6262
                        : $choice
6263
                      ;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
6264
                    }
6265
                  }
6266
                  else if(strict) {
6267
                    module.verbose('Ambiguous dropdown value using strict type check', $choice, value);
6268
                    if( optionValue === value || optionText === value) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if optionValue === value || optionText === value is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
6269
                      $selectedItem = $choice;
6270
                      return true;
6271
                    }
6272
                  }
6273
                  else {
6274
                    if( String(optionValue) == String(value) || optionText == value) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if String(optionValue) == S... || optionText == value is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
6275
                      module.verbose('Found select item by value', optionValue, value);
6276
                      $selectedItem = $choice;
6277
                      return true;
6278
                    }
6279
                  }
6280
                })
6281
              ;
6282
            }
6283
            return $selectedItem;
6284
          }
6285
        },
6286
6287
        check: {
6288
          maxSelections: function(selectionCount) {
6289
            if(settings.maxSelections) {
6290
              selectionCount = (selectionCount !== undefined)
6291
                ? selectionCount
6292
                : module.get.selectionCount()
6293
              ;
6294
              if(selectionCount >= settings.maxSelections) {
6295
                module.debug('Maximum selection count reached');
6296
                if(settings.useLabels) {
6297
                  $item.addClass(className.filtered);
6298
                  module.add.message(message.maxSelections);
6299
                }
6300
                return true;
6301
              }
6302
              else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
6303
                module.verbose('No longer at maximum selection count');
6304
                module.remove.message();
6305
                module.remove.filteredItem();
6306
                if(module.is.searchSelection()) {
6307
                  module.filterItems();
6308
                }
6309
                return false;
6310
              }
6311
            }
6312
            return true;
6313
          }
6314
        },
6315
6316
        restore: {
6317
          defaults: function() {
6318
            module.clear();
6319
            module.restore.defaultText();
6320
            module.restore.defaultValue();
6321
          },
6322
          defaultText: function() {
6323
            var
6324
              defaultText     = module.get.defaultText(),
6325
              placeholderText = module.get.placeholderText
6326
            ;
6327
            if(defaultText === placeholderText) {
6328
              module.debug('Restoring default placeholder text', defaultText);
6329
              module.set.placeholderText(defaultText);
6330
            }
6331
            else {
6332
              module.debug('Restoring default text', defaultText);
6333
              module.set.text(defaultText);
6334
            }
6335
          },
6336
          placeholderText: function() {
6337
            module.set.placeholderText();
6338
          },
6339
          defaultValue: function() {
6340
            var
6341
              defaultValue = module.get.defaultValue()
6342
            ;
6343
            if(defaultValue !== undefined) {
6344
              module.debug('Restoring default value', defaultValue);
6345
              if(defaultValue !== '') {
6346
                module.set.value(defaultValue);
6347
                module.set.selected();
6348
              }
6349
              else {
6350
                module.remove.activeItem();
6351
                module.remove.selectedItem();
6352
              }
6353
            }
6354
          },
6355
          labels: function() {
6356
            if(settings.allowAdditions) {
6357
              if(!settings.useLabels) {
6358
                module.error(error.labels);
6359
                settings.useLabels = true;
6360
              }
6361
              module.debug('Restoring selected values');
6362
              module.create.userLabels();
6363
            }
6364
            module.check.maxSelections();
6365
          },
6366
          selected: function() {
6367
            module.restore.values();
6368
            if(module.is.multiple()) {
6369
              module.debug('Restoring previously selected values and labels');
6370
              module.restore.labels();
6371
            }
6372
            else {
6373
              module.debug('Restoring previously selected values');
6374
            }
6375
          },
6376
          values: function() {
6377
            // prevents callbacks from occurring on initial load
6378
            module.set.initialLoad();
6379
            if(settings.apiSettings && settings.saveRemoteData && module.get.remoteValues()) {
6380
              module.restore.remoteValues();
6381
            }
6382
            else {
6383
              module.set.selected();
6384
            }
6385
            module.remove.initialLoad();
6386
          },
6387
          remoteValues: function() {
6388
            var
6389
              values = module.get.remoteValues()
6390
            ;
6391
            module.debug('Recreating selected from session data', values);
6392
            if(values) {
6393
              if( module.is.single() ) {
6394
                $.each(values, function(value, name) {
6395
                  module.set.text(name);
6396
                });
6397
              }
6398
              else {
6399
                $.each(values, function(value, name) {
6400
                  module.add.label(value, name);
6401
                });
6402
              }
6403
            }
6404
          }
6405
        },
6406
6407
        read: {
6408
          remoteData: function(value) {
6409
            var
6410
              name
6411
            ;
6412
            if(window.Storage === undefined) {
6413
              module.error(error.noStorage);
6414
              return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
6415
            }
6416
            name = sessionStorage.getItem(value);
0 ignored issues
show
Bug introduced by
The variable sessionStorage seems to be never declared. If this is a global, consider adding a /** global: sessionStorage */ 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...
6417
            return (name !== undefined)
6418
              ? name
6419
              : false
6420
            ;
6421
          }
6422
        },
6423
6424
        save: {
6425
          defaults: function() {
6426
            module.save.defaultText();
6427
            module.save.placeholderText();
6428
            module.save.defaultValue();
6429
          },
6430
          defaultValue: function() {
6431
            var
6432
              value = module.get.value()
6433
            ;
6434
            module.verbose('Saving default value as', value);
6435
            $module.data(metadata.defaultValue, value);
6436
          },
6437
          defaultText: function() {
6438
            var
6439
              text = module.get.text()
6440
            ;
6441
            module.verbose('Saving default text as', text);
6442
            $module.data(metadata.defaultText, text);
6443
          },
6444
          placeholderText: function() {
6445
            var
6446
              text
6447
            ;
6448
            if(settings.placeholder !== false && $text.hasClass(className.placeholder)) {
6449
              text = module.get.text();
6450
              module.verbose('Saving placeholder text as', text);
6451
              $module.data(metadata.placeholderText, text);
6452
            }
6453
          },
6454
          remoteData: function(name, value) {
6455
            if(window.Storage === undefined) {
6456
              module.error(error.noStorage);
6457
              return;
6458
            }
6459
            module.verbose('Saving remote data to session storage', value, name);
6460
            sessionStorage.setItem(value, name);
0 ignored issues
show
Bug introduced by
The variable sessionStorage seems to be never declared. If this is a global, consider adding a /** global: sessionStorage */ 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...
6461
          }
6462
        },
6463
6464
        clear: function() {
6465
          if(module.is.multiple() && settings.useLabels) {
6466
            module.remove.labels();
6467
          }
6468
          else {
6469
            module.remove.activeItem();
6470
            module.remove.selectedItem();
6471
          }
6472
          module.set.placeholderText();
6473
          module.clearValue();
6474
        },
6475
6476
        clearValue: function() {
6477
          module.set.value('');
6478
        },
6479
6480
        scrollPage: function(direction, $selectedItem) {
6481
          var
6482
            $currentItem  = $selectedItem || module.get.selectedItem(),
6483
            $menu         = $currentItem.closest(selector.menu),
6484
            menuHeight    = $menu.outerHeight(),
6485
            currentScroll = $menu.scrollTop(),
6486
            itemHeight    = $item.eq(0).outerHeight(),
6487
            itemsPerPage  = Math.floor(menuHeight / itemHeight),
6488
            maxScroll     = $menu.prop('scrollHeight'),
0 ignored issues
show
Unused Code introduced by
The variable maxScroll seems to be never used. Consider removing it.
Loading history...
6489
            newScroll     = (direction == 'up')
6490
              ? currentScroll - (itemHeight * itemsPerPage)
6491
              : currentScroll + (itemHeight * itemsPerPage),
6492
            $selectableItem = $item.not(selector.unselectable),
6493
            isWithinRange,
6494
            $nextSelectedItem,
6495
            elementIndex
6496
          ;
6497
          elementIndex      = (direction == 'up')
6498
            ? $selectableItem.index($currentItem) - itemsPerPage
6499
            : $selectableItem.index($currentItem) + itemsPerPage
6500
          ;
6501
          isWithinRange = (direction == 'up')
6502
            ? (elementIndex >= 0)
6503
            : (elementIndex < $selectableItem.length)
6504
          ;
6505
          $nextSelectedItem = (isWithinRange)
6506
            ? $selectableItem.eq(elementIndex)
6507
            : (direction == 'up')
6508
              ? $selectableItem.first()
6509
              : $selectableItem.last()
6510
          ;
6511
          if($nextSelectedItem.length > 0) {
6512
            module.debug('Scrolling page', direction, $nextSelectedItem);
6513
            $currentItem
6514
              .removeClass(className.selected)
6515
            ;
6516
            $nextSelectedItem
6517
              .addClass(className.selected)
6518
            ;
6519
            if(settings.selectOnKeydown && module.is.single()) {
6520
              module.set.selectedItem($nextSelectedItem);
6521
            }
6522
            $menu
6523
              .scrollTop(newScroll)
6524
            ;
6525
          }
6526
        },
6527
6528
        set: {
6529
          filtered: function() {
6530
            var
6531
              isMultiple       = module.is.multiple(),
6532
              isSearch         = module.is.searchSelection(),
6533
              isSearchMultiple = (isMultiple && isSearch),
6534
              searchValue      = (isSearch)
6535
                ? module.get.query()
6536
                : '',
6537
              hasSearchValue   = (typeof searchValue === 'string' && searchValue.length > 0),
6538
              searchWidth      = module.get.searchWidth(),
6539
              valueIsSet       = searchValue !== ''
6540
            ;
6541
            if(isMultiple && hasSearchValue) {
6542
              module.verbose('Adjusting input width', searchWidth, settings.glyphWidth);
6543
              $search.css('width', searchWidth);
6544
            }
6545
            if(hasSearchValue || (isSearchMultiple && valueIsSet)) {
6546
              module.verbose('Hiding placeholder text');
6547
              $text.addClass(className.filtered);
6548
            }
6549
            else if(!isMultiple || (isSearchMultiple && !valueIsSet)) {
6550
              module.verbose('Showing placeholder text');
6551
              $text.removeClass(className.filtered);
6552
            }
6553
          },
6554
          empty: function() {
6555
            $module.addClass(className.empty);
6556
          },
6557
          loading: function() {
6558
            $module.addClass(className.loading);
6559
          },
6560
          placeholderText: function(text) {
6561
            text = text || module.get.placeholderText();
6562
            module.debug('Setting placeholder text', text);
6563
            module.set.text(text);
6564
            $text.addClass(className.placeholder);
6565
          },
6566
          tabbable: function() {
6567
            if( module.is.searchSelection() ) {
6568
              module.debug('Added tabindex to searchable dropdown');
6569
              $search
6570
                .val('')
6571
                .attr('tabindex', 0)
6572
              ;
6573
              $menu
6574
                .attr('tabindex', -1)
6575
              ;
6576
            }
6577
            else {
6578
              module.debug('Added tabindex to dropdown');
6579
              if( $module.attr('tabindex') === undefined) {
6580
                $module
6581
                  .attr('tabindex', 0)
6582
                ;
6583
                $menu
6584
                  .attr('tabindex', -1)
6585
                ;
6586
              }
6587
            }
6588
          },
6589
          initialLoad: function() {
6590
            module.verbose('Setting initial load');
6591
            initialLoad = true;
6592
          },
6593
          activeItem: function($item) {
6594
            if( settings.allowAdditions && $item.filter(selector.addition).length > 0 ) {
6595
              $item.addClass(className.filtered);
6596
            }
6597
            else {
6598
              $item.addClass(className.active);
6599
            }
6600
          },
6601
          partialSearch: function(text) {
6602
            var
6603
              length = module.get.query().length
6604
            ;
6605
            $search.val( text.substr(0 , length));
6606
          },
6607
          scrollPosition: function($item, forceScroll) {
6608
            var
6609
              edgeTolerance = 5,
6610
              $menu,
6611
              hasActive,
6612
              offset,
6613
              itemHeight,
0 ignored issues
show
Unused Code introduced by
The variable itemHeight seems to be never used. Consider removing it.
Loading history...
6614
              itemOffset,
6615
              menuOffset,
6616
              menuScroll,
6617
              menuHeight,
6618
              abovePage,
6619
              belowPage
6620
            ;
6621
6622
            $item       = $item || module.get.selectedItem();
6623
            $menu       = $item.closest(selector.menu);
6624
            hasActive   = ($item && $item.length > 0);
6625
            forceScroll = (forceScroll !== undefined)
6626
              ? forceScroll
6627
              : false
6628
            ;
6629
            if($item && $menu.length > 0 && hasActive) {
6630
              itemOffset = $item.position().top;
0 ignored issues
show
Unused Code introduced by
The assignment to variable itemOffset seems to be never used. Consider removing it.
Loading history...
6631
6632
              $menu.addClass(className.loading);
6633
              menuScroll = $menu.scrollTop();
6634
              menuOffset = $menu.offset().top;
6635
              itemOffset = $item.offset().top;
6636
              offset     = menuScroll - menuOffset + itemOffset;
6637
              if(!forceScroll) {
6638
                menuHeight = $menu.height();
6639
                belowPage  = menuScroll + menuHeight < (offset + edgeTolerance);
6640
                abovePage  = ((offset - edgeTolerance) < menuScroll);
6641
              }
6642
              module.debug('Scrolling to active item', offset);
6643
              if(forceScroll || abovePage || belowPage) {
6644
                $menu.scrollTop(offset);
6645
              }
6646
              $menu.removeClass(className.loading);
6647
            }
6648
          },
6649
          text: function(text) {
6650
            if(settings.action !== 'select') {
6651
              if(settings.action == 'combo') {
6652
                module.debug('Changing combo button text', text, $combo);
6653
                if(settings.preserveHTML) {
6654
                  $combo.html(text);
6655
                }
6656
                else {
6657
                  $combo.text(text);
6658
                }
6659
              }
6660
              else {
6661
                if(text !== module.get.placeholderText()) {
6662
                  $text.removeClass(className.placeholder);
6663
                }
6664
                module.debug('Changing text', text, $text);
6665
                $text
6666
                  .removeClass(className.filtered)
6667
                ;
6668
                if(settings.preserveHTML) {
6669
                  $text.html(text);
6670
                }
6671
                else {
6672
                  $text.text(text);
6673
                }
6674
              }
6675
            }
6676
          },
6677
          selectedItem: function($item) {
6678
            var
6679
              value      = module.get.choiceValue($item),
6680
              searchText = module.get.choiceText($item, false),
6681
              text       = module.get.choiceText($item, true)
6682
            ;
6683
            module.debug('Setting user selection to item', $item);
6684
            module.remove.activeItem();
6685
            module.set.partialSearch(searchText);
6686
            module.set.activeItem($item);
6687
            module.set.selected(value, $item);
6688
            module.set.text(text);
6689
          },
6690
          selectedLetter: function(letter) {
6691
            var
6692
              $selectedItem         = $item.filter('.' + className.selected),
6693
              alreadySelectedLetter = $selectedItem.length > 0 && module.has.firstLetter($selectedItem, letter),
6694
              $nextValue            = false,
6695
              $nextItem
6696
            ;
6697
            // check next of same letter
6698
            if(alreadySelectedLetter) {
6699
              $nextItem = $selectedItem.nextAll($item).eq(0);
6700
              if( module.has.firstLetter($nextItem, letter) ) {
6701
                $nextValue  = $nextItem;
6702
              }
6703
            }
6704
            // check all values
6705
            if(!$nextValue) {
6706
              $item
6707
                .each(function(){
6708
                  if(module.has.firstLetter($(this), letter)) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if module.has.firstLetter($(this), letter) is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
6709
                    $nextValue = $(this);
6710
                    return false;
6711
                  }
6712
                })
6713
              ;
6714
            }
6715
            // set next value
6716
            if($nextValue) {
6717
              module.verbose('Scrolling to next value with letter', letter);
6718
              module.set.scrollPosition($nextValue);
6719
              $selectedItem.removeClass(className.selected);
6720
              $nextValue.addClass(className.selected);
6721
              if(settings.selectOnKeydown && module.is.single()) {
6722
                module.set.selectedItem($nextValue);
6723
              }
6724
            }
6725
          },
6726
          direction: function($menu) {
6727
            if(settings.direction == 'auto') {
6728
              // reset position
6729
              module.remove.upward();
6730
6731
              if(module.can.openDownward($menu)) {
6732
                module.remove.upward($menu);
6733
              }
6734
              else {
6735
                module.set.upward($menu);
6736
              }
6737
              if(!module.is.leftward($menu) && !module.can.openRightward($menu)) {
6738
                module.set.leftward($menu);
6739
              }
6740
            }
6741
            else if(settings.direction == 'upward') {
6742
              module.set.upward($menu);
6743
            }
6744
          },
6745
          upward: function($currentMenu) {
6746
            var $element = $currentMenu || $module;
6747
            $element.addClass(className.upward);
6748
          },
6749
          leftward: function($currentMenu) {
6750
            var $element = $currentMenu || $menu;
6751
            $element.addClass(className.leftward);
6752
          },
6753
          value: function(value, text, $selected) {
6754
            var
6755
              escapedValue = module.escape.value(value),
6756
              hasInput     = ($input.length > 0),
6757
              isAddition   = !module.has.value(value),
0 ignored issues
show
Unused Code introduced by
The variable isAddition seems to be never used. Consider removing it.
Loading history...
6758
              currentValue = module.get.values(),
6759
              stringValue  = (value !== undefined)
6760
                ? String(value)
6761
                : value,
6762
              newValue
0 ignored issues
show
Unused Code introduced by
The variable newValue seems to be never used. Consider removing it.
Loading history...
6763
            ;
6764
            if(hasInput) {
6765
              if(!settings.allowReselection && stringValue == currentValue) {
6766
                module.verbose('Skipping value update already same value', value, currentValue);
6767
                if(!module.is.initialLoad()) {
6768
                  return;
6769
                }
6770
              }
6771
6772
              if( module.is.single() && module.has.selectInput() && module.can.extendSelect() ) {
6773
                module.debug('Adding user option', value);
6774
                module.add.optionValue(value);
6775
              }
6776
              module.debug('Updating input value', escapedValue, currentValue);
6777
              internalChange = true;
6778
              $input
6779
                .val(escapedValue)
6780
              ;
6781
              if(settings.fireOnInit === false && module.is.initialLoad()) {
6782
                module.debug('Input native change event ignored on initial load');
6783
              }
6784
              else {
6785
                module.trigger.change();
6786
              }
6787
              internalChange = false;
6788
            }
6789
            else {
6790
              module.verbose('Storing value in metadata', escapedValue, $input);
6791
              if(escapedValue !== currentValue) {
6792
                $module.data(metadata.value, stringValue);
6793
              }
6794
            }
6795
            if(settings.fireOnInit === false && module.is.initialLoad()) {
6796
              module.verbose('No callback on initial load', settings.onChange);
6797
            }
6798
            else {
6799
              settings.onChange.call(element, value, text, $selected);
6800
            }
6801
          },
6802
          active: function() {
6803
            $module
6804
              .addClass(className.active)
6805
            ;
6806
          },
6807
          multiple: function() {
6808
            $module.addClass(className.multiple);
6809
          },
6810
          visible: function() {
6811
            $module.addClass(className.visible);
6812
          },
6813
          exactly: function(value, $selectedItem) {
6814
            module.debug('Setting selected to exact values');
6815
            module.clear();
6816
            module.set.selected(value, $selectedItem);
6817
          },
6818
          selected: function(value, $selectedItem) {
6819
            var
6820
              isMultiple = module.is.multiple(),
6821
              $userSelectedItem
0 ignored issues
show
Unused Code introduced by
The variable $userSelectedItem seems to be never used. Consider removing it.
Loading history...
6822
            ;
6823
            $selectedItem = (settings.allowAdditions)
6824
              ? $selectedItem || module.get.itemWithAdditions(value)
6825
              : $selectedItem || module.get.item(value)
6826
            ;
6827
            if(!$selectedItem) {
6828
              return;
6829
            }
6830
            module.debug('Setting selected menu item to', $selectedItem);
6831
            if(module.is.multiple()) {
6832
              module.remove.searchWidth();
6833
            }
6834
            if(module.is.single()) {
6835
              module.remove.activeItem();
6836
              module.remove.selectedItem();
6837
            }
6838
            else if(settings.useLabels) {
6839
              module.remove.selectedItem();
6840
            }
6841
            // select each item
6842
            $selectedItem
6843
              .each(function() {
6844
                var
6845
                  $selected      = $(this),
6846
                  selectedText   = module.get.choiceText($selected),
6847
                  selectedValue  = module.get.choiceValue($selected, selectedText),
6848
6849
                  isFiltered     = $selected.hasClass(className.filtered),
6850
                  isActive       = $selected.hasClass(className.active),
6851
                  isUserValue    = $selected.hasClass(className.addition),
6852
                  shouldAnimate  = (isMultiple && $selectedItem.length == 1)
0 ignored issues
show
Best Practice introduced by
Comparing $selectedItem.length to 1 using the == operator is not safe. Consider using === instead.
Loading history...
6853
                ;
6854
                if(isMultiple) {
6855
                  if(!isActive || isUserValue) {
6856
                    if(settings.apiSettings && settings.saveRemoteData) {
6857
                      module.save.remoteData(selectedText, selectedValue);
6858
                    }
6859
                    if(settings.useLabels) {
6860
                      module.add.value(selectedValue, selectedText, $selected);
6861
                      module.add.label(selectedValue, selectedText, shouldAnimate);
6862
                      module.set.activeItem($selected);
6863
                      module.filterActive();
6864
                      module.select.nextAvailable($selectedItem);
6865
                    }
6866
                    else {
6867
                      module.add.value(selectedValue, selectedText, $selected);
6868
                      module.set.text(module.add.variables(message.count));
6869
                      module.set.activeItem($selected);
6870
                    }
6871
                  }
6872
                  else if(!isFiltered) {
6873
                    module.debug('Selected active value, removing label');
6874
                    module.remove.selected(selectedValue);
6875
                  }
6876
                }
6877
                else {
6878
                  if(settings.apiSettings && settings.saveRemoteData) {
6879
                    module.save.remoteData(selectedText, selectedValue);
6880
                  }
6881
                  module.set.text(selectedText);
6882
                  module.set.value(selectedValue, selectedText, $selected);
6883
                  $selected
6884
                    .addClass(className.active)
6885
                    .addClass(className.selected)
6886
                  ;
6887
                }
6888
              })
6889
            ;
6890
          }
6891
        },
6892
6893
        add: {
6894
          label: function(value, text, shouldAnimate) {
6895
            var
6896
              $next  = module.is.searchSelection()
6897
                ? $search
6898
                : $text,
6899
              escapedValue = module.escape.value(value),
6900
              $label
6901
            ;
6902
            $label =  $('<a />')
6903
              .addClass(className.label)
6904
              .attr('data-' + metadata.value, escapedValue)
6905
              .html(templates.label(escapedValue, text))
6906
            ;
6907
            $label = settings.onLabelCreate.call($label, escapedValue, text);
6908
6909
            if(module.has.label(value)) {
6910
              module.debug('Label already exists, skipping', escapedValue);
6911
              return;
6912
            }
6913
            if(settings.label.variation) {
6914
              $label.addClass(settings.label.variation);
6915
            }
6916
            if(shouldAnimate === true) {
6917
              module.debug('Animating in label', $label);
6918
              $label
6919
                .addClass(className.hidden)
6920
                .insertBefore($next)
6921
                .transition(settings.label.transition, settings.label.duration)
6922
              ;
6923
            }
6924
            else {
6925
              module.debug('Adding selection label', $label);
6926
              $label
6927
                .insertBefore($next)
6928
              ;
6929
            }
6930
          },
6931
          message: function(message) {
6932
            var
6933
              $message = $menu.children(selector.message),
6934
              html     = settings.templates.message(module.add.variables(message))
6935
            ;
6936
            if($message.length > 0) {
6937
              $message
6938
                .html(html)
6939
              ;
6940
            }
6941
            else {
6942
              $message = $('<div/>')
0 ignored issues
show
Unused Code introduced by
The assignment to variable $message seems to be never used. Consider removing it.
Loading history...
6943
                .html(html)
6944
                .addClass(className.message)
6945
                .appendTo($menu)
6946
              ;
6947
            }
6948
          },
6949
          optionValue: function(value) {
6950
            var
6951
              escapedValue = module.escape.value(value),
6952
              $option      = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'),
6953
              hasOption    = ($option.length > 0)
6954
            ;
6955
            if(hasOption) {
6956
              return;
6957
            }
6958
            // temporarily disconnect observer
6959
            module.disconnect.selectObserver();
6960
            if( module.is.single() ) {
6961
              module.verbose('Removing previous user addition');
6962
              $input.find('option.' + className.addition).remove();
6963
            }
6964
            $('<option/>')
6965
              .prop('value', escapedValue)
6966
              .addClass(className.addition)
6967
              .html(value)
6968
              .appendTo($input)
6969
            ;
6970
            module.verbose('Adding user addition as an <option>', value);
6971
            module.observe.select();
6972
          },
6973
          userSuggestion: function(value) {
6974
            var
6975
              $addition         = $menu.children(selector.addition),
6976
              $existingItem     = module.get.item(value),
6977
              alreadyHasValue   = $existingItem && $existingItem.not(selector.addition).length,
6978
              hasUserSuggestion = $addition.length > 0,
6979
              html
6980
            ;
6981
            if(settings.useLabels && module.has.maxSelections()) {
6982
              return;
6983
            }
6984
            if(value === '' || alreadyHasValue) {
6985
              $addition.remove();
6986
              return;
6987
            }
6988
            if(hasUserSuggestion) {
6989
              $addition
6990
                .data(metadata.value, value)
6991
                .data(metadata.text, value)
6992
                .attr('data-' + metadata.value, value)
6993
                .attr('data-' + metadata.text, value)
6994
                .removeClass(className.filtered)
6995
              ;
6996
              if(!settings.hideAdditions) {
6997
                html = settings.templates.addition( module.add.variables(message.addResult, value) );
6998
                $addition
6999
                  .html(html)
7000
                ;
7001
              }
7002
              module.verbose('Replacing user suggestion with new value', $addition);
7003
            }
7004
            else {
7005
              $addition = module.create.userChoice(value);
7006
              $addition
7007
                .prependTo($menu)
7008
              ;
7009
              module.verbose('Adding item choice to menu corresponding with user choice addition', $addition);
7010
            }
7011
            if(!settings.hideAdditions || module.is.allFiltered()) {
7012
              $addition
7013
                .addClass(className.selected)
7014
                .siblings()
7015
                .removeClass(className.selected)
7016
              ;
7017
            }
7018
            module.refreshItems();
7019
          },
7020
          variables: function(message, term) {
7021
            var
7022
              hasCount    = (message.search('{count}') !== -1),
7023
              hasMaxCount = (message.search('{maxCount}') !== -1),
7024
              hasTerm     = (message.search('{term}') !== -1),
7025
              values,
0 ignored issues
show
Unused Code introduced by
The variable values seems to be never used. Consider removing it.
Loading history...
7026
              count,
7027
              query
7028
            ;
7029
            module.verbose('Adding templated variables to message', message);
7030
            if(hasCount) {
7031
              count  = module.get.selectionCount();
7032
              message = message.replace('{count}', count);
7033
            }
7034
            if(hasMaxCount) {
7035
              count  = module.get.selectionCount();
0 ignored issues
show
Unused Code introduced by
The assignment to variable count seems to be never used. Consider removing it.
Loading history...
7036
              message = message.replace('{maxCount}', settings.maxSelections);
7037
            }
7038
            if(hasTerm) {
7039
              query   = term || module.get.query();
7040
              message = message.replace('{term}', query);
7041
            }
7042
            return message;
7043
          },
7044
          value: function(addedValue, addedText, $selectedItem) {
7045
            var
7046
              currentValue = module.get.values(),
7047
              newValue
7048
            ;
7049
            if(addedValue === '') {
7050
              module.debug('Cannot select blank values from multiselect');
7051
              return;
7052
            }
7053
            // extend current array
7054
            if($.isArray(currentValue)) {
7055
              newValue = currentValue.concat([addedValue]);
7056
              newValue = module.get.uniqueArray(newValue);
7057
            }
7058
            else {
7059
              newValue = [addedValue];
7060
            }
7061
            // add values
7062
            if( module.has.selectInput() ) {
7063
              if(module.can.extendSelect()) {
7064
                module.debug('Adding value to select', addedValue, newValue, $input);
7065
                module.add.optionValue(addedValue);
7066
              }
7067
            }
7068
            else {
7069
              newValue = newValue.join(settings.delimiter);
7070
              module.debug('Setting hidden input to delimited value', newValue, $input);
7071
            }
7072
7073
            if(settings.fireOnInit === false && module.is.initialLoad()) {
7074
              module.verbose('Skipping onadd callback on initial load', settings.onAdd);
7075
            }
7076
            else {
7077
              settings.onAdd.call(element, addedValue, addedText, $selectedItem);
7078
            }
7079
            module.set.value(newValue, addedValue, addedText, $selectedItem);
7080
            module.check.maxSelections();
7081
          }
7082
        },
7083
7084
        remove: {
7085
          active: function() {
7086
            $module.removeClass(className.active);
7087
          },
7088
          activeLabel: function() {
7089
            $module.find(selector.label).removeClass(className.active);
7090
          },
7091
          empty: function() {
7092
            $module.removeClass(className.empty);
7093
          },
7094
          loading: function() {
7095
            $module.removeClass(className.loading);
7096
          },
7097
          initialLoad: function() {
7098
            initialLoad = false;
7099
          },
7100
          upward: function($currentMenu) {
7101
            var $element = $currentMenu || $module;
7102
            $element.removeClass(className.upward);
7103
          },
7104
          leftward: function($currentMenu) {
7105
            var $element = $currentMenu || $menu;
7106
            $element.removeClass(className.leftward);
7107
          },
7108
          visible: function() {
7109
            $module.removeClass(className.visible);
7110
          },
7111
          activeItem: function() {
7112
            $item.removeClass(className.active);
7113
          },
7114
          filteredItem: function() {
7115
            if(settings.useLabels && module.has.maxSelections() ) {
7116
              return;
7117
            }
7118
            if(settings.useLabels && module.is.multiple()) {
7119
              $item.not('.' + className.active).removeClass(className.filtered);
7120
            }
7121
            else {
7122
              $item.removeClass(className.filtered);
7123
            }
7124
            module.remove.empty();
7125
          },
7126
          optionValue: function(value) {
7127
            var
7128
              escapedValue = module.escape.value(value),
7129
              $option      = $input.find('option[value="' + module.escape.string(escapedValue) + '"]'),
7130
              hasOption    = ($option.length > 0)
7131
            ;
7132
            if(!hasOption || !$option.hasClass(className.addition)) {
7133
              return;
7134
            }
7135
            // temporarily disconnect observer
7136
            if(selectObserver) {
7137
              selectObserver.disconnect();
7138
              module.verbose('Temporarily disconnecting mutation observer');
7139
            }
7140
            $option.remove();
7141
            module.verbose('Removing user addition as an <option>', escapedValue);
7142
            if(selectObserver) {
7143
              selectObserver.observe($input[0], {
7144
                childList : true,
7145
                subtree   : true
7146
              });
7147
            }
7148
          },
7149
          message: function() {
7150
            $menu.children(selector.message).remove();
7151
          },
7152
          searchWidth: function() {
7153
            $search.css('width', '');
7154
          },
7155
          searchTerm: function() {
7156
            module.verbose('Cleared search term');
7157
            $search.val('');
7158
            module.set.filtered();
7159
          },
7160
          userAddition: function() {
7161
            $item.filter(selector.addition).remove();
7162
          },
7163
          selected: function(value, $selectedItem) {
7164
            $selectedItem = (settings.allowAdditions)
7165
              ? $selectedItem || module.get.itemWithAdditions(value)
7166
              : $selectedItem || module.get.item(value)
7167
            ;
7168
7169
            if(!$selectedItem) {
7170
              return false;
7171
            }
7172
7173
            $selectedItem
7174
              .each(function() {
7175
                var
7176
                  $selected     = $(this),
7177
                  selectedText  = module.get.choiceText($selected),
7178
                  selectedValue = module.get.choiceValue($selected, selectedText)
7179
                ;
7180
                if(module.is.multiple()) {
7181
                  if(settings.useLabels) {
7182
                    module.remove.value(selectedValue, selectedText, $selected);
7183
                    module.remove.label(selectedValue);
7184
                  }
7185
                  else {
7186
                    module.remove.value(selectedValue, selectedText, $selected);
7187
                    if(module.get.selectionCount() === 0) {
7188
                      module.set.placeholderText();
7189
                    }
7190
                    else {
7191
                      module.set.text(module.add.variables(message.count));
7192
                    }
7193
                  }
7194
                }
7195
                else {
7196
                  module.remove.value(selectedValue, selectedText, $selected);
7197
                }
7198
                $selected
7199
                  .removeClass(className.filtered)
7200
                  .removeClass(className.active)
7201
                ;
7202
                if(settings.useLabels) {
7203
                  $selected.removeClass(className.selected);
7204
                }
7205
              })
7206
            ;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
7207
          },
7208
          selectedItem: function() {
7209
            $item.removeClass(className.selected);
7210
          },
7211
          value: function(removedValue, removedText, $removedItem) {
7212
            var
7213
              values = module.get.values(),
7214
              newValue
7215
            ;
7216
            if( module.has.selectInput() ) {
7217
              module.verbose('Input is <select> removing selected option', removedValue);
7218
              newValue = module.remove.arrayValue(removedValue, values);
7219
              module.remove.optionValue(removedValue);
7220
            }
7221
            else {
7222
              module.verbose('Removing from delimited values', removedValue);
7223
              newValue = module.remove.arrayValue(removedValue, values);
7224
              newValue = newValue.join(settings.delimiter);
7225
            }
7226
            if(settings.fireOnInit === false && module.is.initialLoad()) {
7227
              module.verbose('No callback on initial load', settings.onRemove);
7228
            }
7229
            else {
7230
              settings.onRemove.call(element, removedValue, removedText, $removedItem);
7231
            }
7232
            module.set.value(newValue, removedText, $removedItem);
7233
            module.check.maxSelections();
7234
          },
7235
          arrayValue: function(removedValue, values) {
7236
            if( !$.isArray(values) ) {
7237
              values = [values];
7238
            }
7239
            values = $.grep(values, function(value){
7240
              return (removedValue != value);
7241
            });
7242
            module.verbose('Removed value from delimited string', removedValue, values);
7243
            return values;
7244
          },
7245
          label: function(value, shouldAnimate) {
0 ignored issues
show
Unused Code introduced by
The parameter shouldAnimate is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
7246
            var
7247
              $labels       = $module.find(selector.label),
7248
              $removedLabel = $labels.filter('[data-' + metadata.value + '="' + module.escape.string(value) +'"]')
7249
            ;
7250
            module.verbose('Removing label', $removedLabel);
7251
            $removedLabel.remove();
7252
          },
7253
          activeLabels: function($activeLabels) {
7254
            $activeLabels = $activeLabels || $module.find(selector.label).filter('.' + className.active);
7255
            module.verbose('Removing active label selections', $activeLabels);
7256
            module.remove.labels($activeLabels);
7257
          },
7258
          labels: function($labels) {
7259
            $labels = $labels || $module.find(selector.label);
7260
            module.verbose('Removing labels', $labels);
7261
            $labels
7262
              .each(function(){
7263
                var
7264
                  $label      = $(this),
7265
                  value       = $label.data(metadata.value),
7266
                  stringValue = (value !== undefined)
7267
                    ? String(value)
7268
                    : value,
7269
                  isUserValue = module.is.userValue(stringValue)
7270
                ;
7271
                if(settings.onLabelRemove.call($label, value) === false) {
7272
                  module.debug('Label remove callback cancelled removal');
7273
                  return;
7274
                }
7275
                module.remove.message();
7276
                if(isUserValue) {
7277
                  module.remove.value(stringValue);
7278
                  module.remove.label(stringValue);
7279
                }
7280
                else {
7281
                  // selected will also remove label
7282
                  module.remove.selected(stringValue);
7283
                }
7284
              })
7285
            ;
7286
          },
7287
          tabbable: function() {
7288
            if( module.is.searchSelection() ) {
7289
              module.debug('Searchable dropdown initialized');
7290
              $search
7291
                .removeAttr('tabindex')
7292
              ;
7293
              $menu
7294
                .removeAttr('tabindex')
7295
              ;
7296
            }
7297
            else {
7298
              module.debug('Simple selection dropdown initialized');
7299
              $module
7300
                .removeAttr('tabindex')
7301
              ;
7302
              $menu
7303
                .removeAttr('tabindex')
7304
              ;
7305
            }
7306
          }
7307
        },
7308
7309
        has: {
7310
          menuSearch: function() {
7311
            return (module.has.search() && $search.closest($menu).length > 0);
7312
          },
7313
          search: function() {
7314
            return ($search.length > 0);
7315
          },
7316
          sizer: function() {
7317
            return ($sizer.length > 0);
7318
          },
7319
          selectInput: function() {
7320
            return ( $input.is('select') );
7321
          },
7322
          minCharacters: function(searchTerm) {
7323
            if(settings.minCharacters) {
7324
              searchTerm = (searchTerm !== undefined)
7325
                ? String(searchTerm)
7326
                : String(module.get.query())
7327
              ;
7328
              return (searchTerm.length >= settings.minCharacters);
7329
            }
7330
            return true;
7331
          },
7332
          firstLetter: function($item, letter) {
7333
            var
7334
              text,
7335
              firstLetter
7336
            ;
7337
            if(!$item || $item.length === 0 || typeof letter !== 'string') {
7338
              return false;
7339
            }
7340
            text        = module.get.choiceText($item, false);
7341
            letter      = letter.toLowerCase();
7342
            firstLetter = String(text).charAt(0).toLowerCase();
7343
            return (letter == firstLetter);
7344
          },
7345
          input: function() {
7346
            return ($input.length > 0);
7347
          },
7348
          items: function() {
7349
            return ($item.length > 0);
7350
          },
7351
          menu: function() {
7352
            return ($menu.length > 0);
7353
          },
7354
          message: function() {
7355
            return ($menu.children(selector.message).length !== 0);
7356
          },
7357
          label: function(value) {
7358
            var
7359
              escapedValue = module.escape.value(value),
7360
              $labels      = $module.find(selector.label)
7361
            ;
7362
            return ($labels.filter('[data-' + metadata.value + '="' + module.escape.string(escapedValue) +'"]').length > 0);
7363
          },
7364
          maxSelections: function() {
7365
            return (settings.maxSelections && module.get.selectionCount() >= settings.maxSelections);
7366
          },
7367
          allResultsFiltered: function() {
7368
            var
7369
              $normalResults = $item.not(selector.addition)
7370
            ;
7371
            return ($normalResults.filter(selector.unselectable).length === $normalResults.length);
7372
          },
7373
          userSuggestion: function() {
7374
            return ($menu.children(selector.addition).length > 0);
7375
          },
7376
          query: function() {
7377
            return (module.get.query() !== '');
7378
          },
7379
          value: function(value) {
7380
            var
7381
              values   = module.get.values(),
7382
              hasValue = $.isArray(values)
7383
               ? values && ($.inArray(value, values) !== -1)
7384
               : (values == value)
7385
            ;
7386
            return (hasValue)
7387
              ? true
7388
              : false
7389
            ;
7390
          }
7391
        },
7392
7393
        is: {
7394
          active: function() {
7395
            return $module.hasClass(className.active);
7396
          },
7397
          bubbledLabelClick: function(event) {
7398
            return $(event.target).is('select, input') && $module.closest('label').length > 0;
7399
          },
7400
          bubbledIconClick: function(event) {
7401
            return $(event.target).closest($icon).length > 0;
7402
          },
7403
          alreadySetup: function() {
7404
            return ($module.is('select') && $module.parent(selector.dropdown).length > 0  && $module.prev().length === 0);
7405
          },
7406
          animating: function($subMenu) {
7407
            return ($subMenu)
7408
              ? $subMenu.transition && $subMenu.transition('is animating')
7409
              : $menu.transition    && $menu.transition('is animating')
7410
            ;
7411
          },
7412
          leftward: function($subMenu) {
7413
            var $selectedMenu = $subMenu || $menu;
7414
            return $selectedMenu.hasClass(className.leftward);
7415
          },
7416
          disabled: function() {
7417
            return $module.hasClass(className.disabled);
7418
          },
7419
          focused: function() {
7420
            return (document.activeElement === $module[0]);
7421
          },
7422
          focusedOnSearch: function() {
7423
            return (document.activeElement === $search[0]);
7424
          },
7425
          allFiltered: function() {
7426
            return( (module.is.multiple() || module.has.search()) && !(settings.hideAdditions == false && module.has.userSuggestion()) && !module.has.message() && module.has.allResultsFiltered() );
0 ignored issues
show
Best Practice introduced by
Comparing settings.hideAdditions to false using the == operator is not safe. Consider using === instead.
Loading history...
7427
          },
7428
          hidden: function($subMenu) {
7429
            return !module.is.visible($subMenu);
7430
          },
7431
          initialLoad: function() {
7432
            return initialLoad;
7433
          },
7434
          inObject: function(needle, object) {
7435
            var
7436
              found = false
7437
            ;
7438
            $.each(object, function(index, property) {
7439
              if(property == needle) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if property == needle is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
7440
                found = true;
7441
                return true;
7442
              }
7443
            });
7444
            return found;
7445
          },
7446
          multiple: function() {
7447
            return $module.hasClass(className.multiple);
7448
          },
7449
          remote: function() {
7450
            return settings.apiSettings && module.can.useAPI();
7451
          },
7452
          single: function() {
7453
            return !module.is.multiple();
7454
          },
7455
          selectMutation: function(mutations) {
7456
            var
7457
              selectChanged = false
7458
            ;
7459
            $.each(mutations, function(index, mutation) {
7460
              if(mutation.target && $(mutation.target).is('select')) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if mutation.target && $(mut...on.target).is("select") is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
7461
                selectChanged = true;
7462
                return true;
7463
              }
7464
            });
7465
            return selectChanged;
7466
          },
7467
          search: function() {
7468
            return $module.hasClass(className.search);
7469
          },
7470
          searchSelection: function() {
7471
            return ( module.has.search() && $search.parent(selector.dropdown).length === 1 );
7472
          },
7473
          selection: function() {
7474
            return $module.hasClass(className.selection);
7475
          },
7476
          userValue: function(value) {
7477
            return ($.inArray(value, module.get.userValues()) !== -1);
7478
          },
7479
          upward: function($menu) {
7480
            var $element = $menu || $module;
7481
            return $element.hasClass(className.upward);
7482
          },
7483
          visible: function($subMenu) {
7484
            return ($subMenu)
7485
              ? $subMenu.hasClass(className.visible)
7486
              : $menu.hasClass(className.visible)
7487
            ;
7488
          },
7489
          verticallyScrollableContext: function() {
7490
            var
7491
              overflowY = ($context.get(0) !== window)
7492
                ? $context.css('overflow-y')
7493
                : false
7494
            ;
7495
            return (overflowY == 'auto' || overflowY == 'scroll');
7496
          },
7497
          horizontallyScrollableContext: function() {
7498
            var
7499
              overflowX = ($context.get(0) !== window)
7500
                ? $context.css('overflow-X')
7501
                : false
7502
            ;
7503
            return (overflowX == 'auto' || overflowX == 'scroll');
7504
          }
7505
        },
7506
7507
        can: {
7508
          activate: function($item) {
7509
            if(settings.useLabels) {
7510
              return true;
7511
            }
7512
            if(!module.has.maxSelections()) {
7513
              return true;
7514
            }
7515
            if(module.has.maxSelections() && $item.hasClass(className.active)) {
7516
              return true;
7517
            }
7518
            return false;
7519
          },
7520
          openDownward: function($subMenu) {
7521
            var
7522
              $currentMenu    = $subMenu || $menu,
7523
              canOpenDownward = true,
0 ignored issues
show
Unused Code introduced by
The assignment to variable canOpenDownward seems to be never used. Consider removing it.
Loading history...
7524
              onScreen        = {},
0 ignored issues
show
Unused Code introduced by
The assignment to variable onScreen seems to be never used. Consider removing it.
Loading history...
7525
              calculations
7526
            ;
7527
            $currentMenu
7528
              .addClass(className.loading)
7529
            ;
7530
            calculations = {
7531
              context: {
7532
                scrollTop : $context.scrollTop(),
7533
                height    : $context.outerHeight()
7534
              },
7535
              menu : {
7536
                offset: $currentMenu.offset(),
7537
                height: $currentMenu.outerHeight()
7538
              }
7539
            };
7540
            if(module.is.verticallyScrollableContext()) {
7541
              calculations.menu.offset.top += calculations.context.scrollTop;
7542
            }
7543
            onScreen = {
7544
              above : (calculations.context.scrollTop) <= calculations.menu.offset.top - calculations.menu.height,
7545
              below : (calculations.context.scrollTop + calculations.context.height) >= calculations.menu.offset.top + calculations.menu.height
7546
            };
7547
            if(onScreen.below) {
7548
              module.verbose('Dropdown can fit in context downward', onScreen);
7549
              canOpenDownward = true;
7550
            }
7551
            else if(!onScreen.below && !onScreen.above) {
7552
              module.verbose('Dropdown cannot fit in either direction, favoring downward', onScreen);
7553
              canOpenDownward = true;
7554
            }
7555
            else {
7556
              module.verbose('Dropdown cannot fit below, opening upward', onScreen);
7557
              canOpenDownward = false;
7558
            }
7559
            $currentMenu.removeClass(className.loading);
7560
            return canOpenDownward;
7561
          },
7562
          openRightward: function($subMenu) {
7563
            var
7564
              $currentMenu     = $subMenu || $menu,
7565
              canOpenRightward = true,
7566
              isOffscreenRight = false,
0 ignored issues
show
Unused Code introduced by
The assignment to variable isOffscreenRight seems to be never used. Consider removing it.
Loading history...
7567
              calculations
7568
            ;
7569
            $currentMenu
7570
              .addClass(className.loading)
7571
            ;
7572
            calculations = {
7573
              context: {
7574
                scrollLeft : $context.scrollLeft(),
7575
                width      : $context.outerWidth()
7576
              },
7577
              menu: {
7578
                offset : $currentMenu.offset(),
7579
                width  : $currentMenu.outerWidth()
7580
              }
7581
            };
7582
            if(module.is.horizontallyScrollableContext()) {
7583
              calculations.menu.offset.left += calculations.context.scrollLeft;
7584
            }
7585
            isOffscreenRight = (calculations.menu.offset.left + calculations.menu.width >= calculations.context.scrollLeft + calculations.context.width);
7586
            if(isOffscreenRight) {
7587
              module.verbose('Dropdown cannot fit in context rightward', isOffscreenRight);
7588
              canOpenRightward = false;
7589
            }
7590
            $currentMenu.removeClass(className.loading);
7591
            return canOpenRightward;
7592
          },
7593
          click: function() {
7594
            return (hasTouch || settings.on == 'click');
7595
          },
7596
          extendSelect: function() {
7597
            return settings.allowAdditions || settings.apiSettings;
7598
          },
7599
          show: function() {
7600
            return !module.is.disabled() && (module.has.items() || module.has.message());
7601
          },
7602
          useAPI: function() {
7603
            return $.fn.api !== undefined;
7604
          }
7605
        },
7606
7607
        animate: {
7608
          show: function(callback, $subMenu) {
7609
            var
7610
              $currentMenu = $subMenu || $menu,
7611
              start = ($subMenu)
7612
                ? function() {}
7613
                : function() {
7614
                  module.hideSubMenus();
7615
                  module.hideOthers();
7616
                  module.set.active();
7617
                },
7618
              transition
7619
            ;
7620
            callback = $.isFunction(callback)
7621
              ? callback
7622
              : function(){}
7623
            ;
7624
            module.verbose('Doing menu show animation', $currentMenu);
7625
            module.set.direction($subMenu);
7626
            transition = module.get.transition($subMenu);
7627
            if( module.is.selection() ) {
7628
              module.set.scrollPosition(module.get.selectedItem(), true);
7629
            }
7630
            if( module.is.hidden($currentMenu) || module.is.animating($currentMenu) ) {
7631
              if(transition == 'none') {
7632
                start();
7633
                $currentMenu.transition('show');
7634
                callback.call(element);
7635
              }
7636
              else if($.fn.transition !== undefined && $module.transition('is supported')) {
7637
                $currentMenu
7638
                  .transition({
7639
                    animation  : transition + ' in',
7640
                    debug      : settings.debug,
7641
                    verbose    : settings.verbose,
7642
                    duration   : settings.duration,
7643
                    queue      : true,
7644
                    onStart    : start,
7645
                    onComplete : function() {
7646
                      callback.call(element);
7647
                    }
7648
                  })
7649
                ;
7650
              }
7651
              else {
7652
                module.error(error.noTransition, transition);
7653
              }
7654
            }
7655
          },
7656
          hide: function(callback, $subMenu) {
7657
            var
7658
              $currentMenu = $subMenu || $menu,
7659
              duration = ($subMenu)
7660
                ? (settings.duration * 0.9)
7661
                : settings.duration,
7662
              start = ($subMenu)
7663
                ? function() {}
7664
                : function() {
7665
                  if( module.can.click() ) {
7666
                    module.unbind.intent();
7667
                  }
7668
                  module.remove.active();
7669
                },
7670
              transition = module.get.transition($subMenu)
7671
            ;
7672
            callback = $.isFunction(callback)
7673
              ? callback
7674
              : function(){}
7675
            ;
7676
            if( module.is.visible($currentMenu) || module.is.animating($currentMenu) ) {
7677
              module.verbose('Doing menu hide animation', $currentMenu);
7678
7679
              if(transition == 'none') {
7680
                start();
7681
                $currentMenu.transition('hide');
7682
                callback.call(element);
7683
              }
7684
              else if($.fn.transition !== undefined && $module.transition('is supported')) {
7685
                $currentMenu
7686
                  .transition({
7687
                    animation  : transition + ' out',
7688
                    duration   : settings.duration,
7689
                    debug      : settings.debug,
7690
                    verbose    : settings.verbose,
7691
                    queue      : true,
7692
                    onStart    : start,
7693
                    onComplete : function() {
7694
                      callback.call(element);
7695
                    }
7696
                  })
7697
                ;
7698
              }
7699
              else {
7700
                module.error(error.transition);
7701
              }
7702
            }
7703
          }
7704
        },
7705
7706
        hideAndClear: function() {
7707
          module.remove.searchTerm();
7708
          if( module.has.maxSelections() ) {
7709
            return;
7710
          }
7711
          if(module.has.search()) {
7712
            module.hide(function() {
7713
              module.remove.filteredItem();
7714
            });
7715
          }
7716
          else {
7717
            module.hide();
7718
          }
7719
        },
7720
7721
        delay: {
7722
          show: function() {
7723
            module.verbose('Delaying show event to ensure user intent');
7724
            clearTimeout(module.timer);
7725
            module.timer = setTimeout(module.show, settings.delay.show);
7726
          },
7727
          hide: function() {
7728
            module.verbose('Delaying hide event to ensure user intent');
7729
            clearTimeout(module.timer);
7730
            module.timer = setTimeout(module.hide, settings.delay.hide);
7731
          }
7732
        },
7733
7734
        escape: {
7735
          value: function(value) {
7736
            var
7737
              multipleValues = $.isArray(value),
7738
              stringValue    = (typeof value === 'string'),
7739
              isUnparsable   = (!stringValue && !multipleValues),
7740
              hasQuotes      = (stringValue && value.search(regExp.quote) !== -1),
7741
              values         = []
7742
            ;
7743
            if(isUnparsable || !hasQuotes) {
7744
              return value;
7745
            }
7746
            module.debug('Encoding quote values for use in select', value);
7747
            if(multipleValues) {
7748
              $.each(value, function(index, value){
7749
                values.push(value.replace(regExp.quote, '&quot;'));
7750
              });
7751
              return values;
7752
            }
7753
            return value.replace(regExp.quote, '&quot;');
7754
          },
7755
          string: function(text) {
7756
            text =  String(text);
7757
            return text.replace(regExp.escape, '\\$&');
7758
          }
7759
        },
7760
7761
        setting: function(name, value) {
7762
          module.debug('Changing setting', name, value);
7763
          if( $.isPlainObject(name) ) {
7764
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
7765
          }
7766
          else if(value !== undefined) {
7767
            if($.isPlainObject(settings[name])) {
7768
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
7769
            }
7770
            else {
7771
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
7772
            }
7773
          }
7774
          else {
7775
            return settings[name];
7776
          }
7777
        },
7778
        internal: function(name, value) {
7779
          if( $.isPlainObject(name) ) {
7780
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
7781
          }
7782
          else if(value !== undefined) {
7783
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
7784
          }
7785
          else {
7786
            return module[name];
7787
          }
7788
        },
7789
        debug: function() {
7790
          if(!settings.silent && settings.debug) {
7791
            if(settings.performance) {
7792
              module.performance.log(arguments);
7793
            }
7794
            else {
7795
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
7796
              module.debug.apply(console, arguments);
7797
            }
7798
          }
7799
        },
7800
        verbose: function() {
7801
          if(!settings.silent && settings.verbose && settings.debug) {
7802
            if(settings.performance) {
7803
              module.performance.log(arguments);
7804
            }
7805
            else {
7806
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
7807
              module.verbose.apply(console, arguments);
7808
            }
7809
          }
7810
        },
7811
        error: function() {
7812
          if(!settings.silent) {
7813
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
7814
            module.error.apply(console, arguments);
7815
          }
7816
        },
7817
        performance: {
7818
          log: function(message) {
7819
            var
7820
              currentTime,
7821
              executionTime,
7822
              previousTime
7823
            ;
7824
            if(settings.performance) {
7825
              currentTime   = new Date().getTime();
7826
              previousTime  = time || currentTime;
7827
              executionTime = currentTime - previousTime;
7828
              time          = currentTime;
7829
              performance.push({
7830
                'Name'           : message[0],
7831
                'Arguments'      : [].slice.call(message, 1) || '',
7832
                'Element'        : element,
7833
                'Execution Time' : executionTime
7834
              });
7835
            }
7836
            clearTimeout(module.performance.timer);
7837
            module.performance.timer = setTimeout(module.performance.display, 500);
7838
          },
7839
          display: function() {
7840
            var
7841
              title = settings.name + ':',
7842
              totalTime = 0
7843
            ;
7844
            time = false;
7845
            clearTimeout(module.performance.timer);
7846
            $.each(performance, function(index, data) {
7847
              totalTime += data['Execution Time'];
7848
            });
7849
            title += ' ' + totalTime + 'ms';
7850
            if(moduleSelector) {
7851
              title += ' \'' + moduleSelector + '\'';
7852
            }
7853
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
7854
              console.groupCollapsed(title);
7855
              if(console.table) {
7856
                console.table(performance);
7857
              }
7858
              else {
7859
                $.each(performance, function(index, data) {
7860
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
7861
                });
7862
              }
7863
              console.groupEnd();
7864
            }
7865
            performance = [];
7866
          }
7867
        },
7868
        invoke: function(query, passedArguments, context) {
7869
          var
7870
            object = instance,
7871
            maxDepth,
7872
            found,
7873
            response
7874
          ;
7875
          passedArguments = passedArguments || queryArguments;
7876
          context         = element         || context;
7877
          if(typeof query == 'string' && object !== undefined) {
7878
            query    = query.split(/[\. ]/);
7879
            maxDepth = query.length - 1;
7880
            $.each(query, function(depth, value) {
7881
              var camelCaseValue = (depth != maxDepth)
7882
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
7883
                : query
7884
              ;
7885
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
7886
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
7887
              }
7888
              else if( object[camelCaseValue] !== undefined ) {
7889
                found = object[camelCaseValue];
7890
                return false;
7891
              }
7892
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
7893
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
7894
              }
7895
              else if( object[value] !== undefined ) {
7896
                found = object[value];
7897
                return false;
7898
              }
7899
              else {
7900
                module.error(error.method, query);
7901
                return false;
7902
              }
7903
            });
7904
          }
7905
          if ( $.isFunction( found ) ) {
7906
            response = found.apply(context, passedArguments);
7907
          }
7908
          else if(found !== undefined) {
7909
            response = found;
7910
          }
7911
          if($.isArray(returnedValue)) {
7912
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 7908 is false. Are you sure the function push handles undefined variables?
Loading history...
7913
          }
7914
          else if(returnedValue !== undefined) {
7915
            returnedValue = [returnedValue, response];
7916
          }
7917
          else if(response !== undefined) {
7918
            returnedValue = response;
7919
          }
7920
          return found;
7921
        }
7922
      };
7923
7924
      if(methodInvoked) {
7925
        if(instance === undefined) {
7926
          module.initialize();
7927
        }
7928
        module.invoke(query);
7929
      }
7930
      else {
7931
        if(instance !== undefined) {
7932
          instance.invoke('destroy');
7933
        }
7934
        module.initialize();
7935
      }
7936
    })
7937
  ;
7938
  return (returnedValue !== undefined)
7939
    ? returnedValue
7940
    : $allModules
7941
  ;
7942
};
7943
7944
$.fn.dropdown.settings = {
7945
7946
  silent                 : false,
7947
  debug                  : false,
7948
  verbose                : false,
7949
  performance            : true,
7950
7951
  on                     : 'click',    // what event should show menu action on item selection
7952
  action                 : 'activate', // action on item selection (nothing, activate, select, combo, hide, function(){})
7953
7954
7955
  apiSettings            : false,
7956
  selectOnKeydown        : true,       // Whether selection should occur automatically when keyboard shortcuts used
7957
  minCharacters          : 0,          // Minimum characters required to trigger API call
7958
7959
  filterRemoteData       : false,      // Whether API results should be filtered after being returned for query term
7960
  saveRemoteData         : true,       // Whether remote name/value pairs should be stored in sessionStorage to allow remote data to be restored on page refresh
7961
7962
  throttle               : 200,        // How long to wait after last user input to search remotely
7963
7964
  context                : window,     // Context to use when determining if on screen
7965
  direction              : 'auto',     // Whether dropdown should always open in one direction
7966
  keepOnScreen           : true,       // Whether dropdown should check whether it is on screen before showing
7967
7968
  match                  : 'both',     // what to match against with search selection (both, text, or label)
7969
  fullTextSearch         : false,      // search anywhere in value (set to 'exact' to require exact matches)
7970
7971
  placeholder            : 'auto',     // whether to convert blank <select> values to placeholder text
7972
  preserveHTML           : true,       // preserve html when selecting value
7973
  sortSelect             : false,      // sort selection on init
7974
7975
  forceSelection         : true,       // force a choice on blur with search selection
7976
7977
  allowAdditions         : false,      // whether multiple select should allow user added values
7978
  hideAdditions          : true,      // whether or not to hide special message prompting a user they can enter a value
7979
7980
  maxSelections          : false,      // When set to a number limits the number of selections to this count
7981
  useLabels              : true,       // whether multiple select should filter currently active selections from choices
7982
  delimiter              : ',',        // when multiselect uses normal <input> the values will be delimited with this character
7983
7984
  showOnFocus            : true,       // show menu on focus
7985
  allowReselection       : false,      // whether current value should trigger callbacks when reselected
7986
  allowTab               : true,       // add tabindex to element
7987
  allowCategorySelection : false,      // allow elements with sub-menus to be selected
7988
7989
  fireOnInit             : false,      // Whether callbacks should fire when initializing dropdown values
7990
7991
  transition             : 'auto',     // auto transition will slide down or up based on direction
7992
  duration               : 200,        // duration of transition
7993
7994
  glyphWidth             : 1.037,      // widest glyph width in em (W is 1.037 em) used to calculate multiselect input width
7995
7996
  // label settings on multi-select
7997
  label: {
7998
    transition : 'scale',
7999
    duration   : 200,
8000
    variation  : false
8001
  },
8002
8003
  // delay before event
8004
  delay : {
8005
    hide   : 300,
8006
    show   : 200,
8007
    search : 20,
8008
    touch  : 50
8009
  },
8010
8011
  /* Callbacks */
8012
  onChange      : function(value, text, $selected){},
0 ignored issues
show
Unused Code introduced by
The parameter $selected is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter text is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
8013
  onAdd         : function(value, text, $selected){},
0 ignored issues
show
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter text is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter $selected is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
8014
  onRemove      : function(value, text, $selected){},
0 ignored issues
show
Unused Code introduced by
The parameter text is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter $selected is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
8015
8016
  onLabelSelect : function($selectedLabels){},
0 ignored issues
show
Unused Code introduced by
The parameter $selectedLabels is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
8017
  onLabelCreate : function(value, text) { return $(this); },
0 ignored issues
show
Unused Code introduced by
The parameter text is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
8018
  onLabelRemove : function(value) { return true; },
0 ignored issues
show
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
8019
  onNoResults   : function(searchTerm) { return true; },
0 ignored issues
show
Unused Code introduced by
The parameter searchTerm is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
8020
  onShow        : function(){},
8021
  onHide        : function(){},
8022
8023
  /* Component */
8024
  name           : 'Dropdown',
8025
  namespace      : 'dropdown',
8026
8027
  message: {
8028
    addResult     : 'Add <b>{term}</b>',
8029
    count         : '{count} selected',
8030
    maxSelections : 'Max {maxCount} selections',
8031
    noResults     : 'No results found.',
8032
    serverError   : 'There was an error contacting the server'
8033
  },
8034
8035
  error : {
8036
    action          : 'You called a dropdown action that was not defined',
8037
    alreadySetup    : 'Once a select has been initialized behaviors must be called on the created ui dropdown',
8038
    labels          : 'Allowing user additions currently requires the use of labels.',
8039
    missingMultiple : '<select> requires multiple property to be set to correctly preserve multiple values',
8040
    method          : 'The method you called is not defined.',
8041
    noAPI           : 'The API module is required to load resources remotely',
8042
    noStorage       : 'Saving remote data requires session storage',
8043
    noTransition    : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>'
8044
  },
8045
8046
  regExp : {
8047
    escape   : /[-[\]{}()*+?.,\\^$|#\s]/g,
8048
    quote    : /"/g
8049
  },
8050
8051
  metadata : {
8052
    defaultText     : 'defaultText',
8053
    defaultValue    : 'defaultValue',
8054
    placeholderText : 'placeholder',
8055
    text            : 'text',
8056
    value           : 'value'
8057
  },
8058
8059
  // property names for remote query
8060
  fields: {
8061
    remoteValues : 'results',  // grouping for api results
8062
    values       : 'values',   // grouping for all dropdown values
8063
    disabled     : 'disabled', // whether value should be disabled
8064
    name         : 'name',     // displayed dropdown text
8065
    value        : 'value',    // actual dropdown value
8066
    text         : 'text'      // displayed text when selected
8067
  },
8068
8069
  keys : {
8070
    backspace  : 8,
8071
    delimiter  : 188, // comma
8072
    deleteKey  : 46,
8073
    enter      : 13,
8074
    escape     : 27,
8075
    pageUp     : 33,
8076
    pageDown   : 34,
8077
    leftArrow  : 37,
8078
    upArrow    : 38,
8079
    rightArrow : 39,
8080
    downArrow  : 40
8081
  },
8082
8083
  selector : {
8084
    addition     : '.addition',
8085
    dropdown     : '.ui.dropdown',
8086
    hidden       : '.hidden',
8087
    icon         : '> .dropdown.icon',
8088
    input        : '> input[type="hidden"], > select',
8089
    item         : '.item',
8090
    label        : '> .label',
8091
    remove       : '> .label > .delete.icon',
8092
    siblingLabel : '.label',
8093
    menu         : '.menu',
8094
    message      : '.message',
8095
    menuIcon     : '.dropdown.icon',
8096
    search       : 'input.search, .menu > .search > input, .menu input.search',
8097
    sizer        : '> input.sizer',
8098
    text         : '> .text:not(.icon)',
8099
    unselectable : '.disabled, .filtered'
8100
  },
8101
8102
  className : {
8103
    active      : 'active',
8104
    addition    : 'addition',
8105
    animating   : 'animating',
8106
    disabled    : 'disabled',
8107
    empty       : 'empty',
8108
    dropdown    : 'ui dropdown',
8109
    filtered    : 'filtered',
8110
    hidden      : 'hidden transition',
8111
    item        : 'item',
8112
    label       : 'ui label',
8113
    loading     : 'loading',
8114
    menu        : 'menu',
8115
    message     : 'message',
8116
    multiple    : 'multiple',
8117
    placeholder : 'default',
8118
    sizer       : 'sizer',
8119
    search      : 'search',
8120
    selected    : 'selected',
8121
    selection   : 'selection',
8122
    upward      : 'upward',
8123
    leftward    : 'left',
8124
    visible     : 'visible'
8125
  }
8126
8127
};
8128
8129
/* Templates */
8130
$.fn.dropdown.settings.templates = {
8131
8132
  // generates dropdown from select values
8133
  dropdown: function(select) {
8134
    var
8135
      placeholder = select.placeholder || false,
8136
      values      = select.values || {},
8137
      html        = ''
8138
    ;
8139
    html +=  '<i class="dropdown icon"></i>';
8140
    if(select.placeholder) {
8141
      html += '<div class="default text">' + placeholder + '</div>';
8142
    }
8143
    else {
8144
      html += '<div class="text"></div>';
8145
    }
8146
    html += '<div class="menu">';
8147
    $.each(select.values, function(index, option) {
8148
      html += (option.disabled)
8149
        ? '<div class="disabled item" data-value="' + option.value + '">' + option.name + '</div>'
8150
        : '<div class="item" data-value="' + option.value + '">' + option.name + '</div>'
8151
      ;
8152
    });
8153
    html += '</div>';
8154
    return html;
8155
  },
8156
8157
  // generates just menu from select
8158
  menu: function(response, fields) {
8159
    var
8160
      values = response[fields.values] || {},
8161
      html   = ''
8162
    ;
8163
    $.each(values, function(index, option) {
8164
      var
8165
        maybeText = (option[fields.text])
8166
          ? 'data-text="' + option[fields.text] + '"'
8167
          : '',
8168
        maybeDisabled = (option[fields.disabled])
8169
          ? 'disabled '
8170
          : ''
8171
      ;
8172
      html += '<div class="'+ maybeDisabled +'item" data-value="' + option[fields.value] + '"' + maybeText + '>'
8173
      html +=   option[fields.name];
8174
      html += '</div>';
8175
    });
8176
    return html;
8177
  },
8178
8179
  // generates label for multiselect
8180
  label: function(value, text) {
8181
    return text + '<i class="delete icon"></i>';
8182
  },
8183
8184
8185
  // generates messages like "No results"
8186
  message: function(message) {
8187
    return message;
8188
  },
8189
8190
  // generates user addition to selection menu
8191
  addition: function(choice) {
8192
    return choice;
8193
  }
8194
8195
};
8196
8197
})( jQuery, window, document );
8198
8199
/*!
8200
 * # Semantic UI 2.2.11 - Embed
8201
 * http://github.com/semantic-org/semantic-ui/
8202
 *
8203
 *
8204
 * Released under the MIT license
8205
 * http://opensource.org/licenses/MIT
8206
 *
8207
 */
8208
8209 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
8210
8211
"use strict";
8212
8213
window = (typeof window != 'undefined' && window.Math == Math)
8214
  ? window
8215
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
8216
    ? self
8217
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
8218
;
8219
8220
$.fn.embed = function(parameters) {
8221
8222
  var
8223
    $allModules     = $(this),
8224
8225
    moduleSelector  = $allModules.selector || '',
8226
8227
    time            = new Date().getTime(),
8228
    performance     = [],
8229
8230
    query           = arguments[0],
8231
    methodInvoked   = (typeof query == 'string'),
8232
    queryArguments  = [].slice.call(arguments, 1),
8233
8234
    returnedValue
8235
  ;
8236
8237
  $allModules
8238
    .each(function() {
8239
      var
8240
        settings        = ( $.isPlainObject(parameters) )
8241
          ? $.extend(true, {}, $.fn.embed.settings, parameters)
8242
          : $.extend({}, $.fn.embed.settings),
8243
8244
        selector        = settings.selector,
8245
        className       = settings.className,
8246
        sources         = settings.sources,
8247
        error           = settings.error,
8248
        metadata        = settings.metadata,
8249
        namespace       = settings.namespace,
8250
        templates       = settings.templates,
8251
8252
        eventNamespace  = '.' + namespace,
8253
        moduleNamespace = 'module-' + namespace,
8254
8255
        $window         = $(window),
0 ignored issues
show
Unused Code introduced by
The variable $window seems to be never used. Consider removing it.
Loading history...
8256
        $module         = $(this),
8257
        $placeholder    = $module.find(selector.placeholder),
0 ignored issues
show
Unused Code introduced by
The variable $placeholder seems to be never used. Consider removing it.
Loading history...
8258
        $icon           = $module.find(selector.icon),
0 ignored issues
show
Unused Code introduced by
The variable $icon seems to be never used. Consider removing it.
Loading history...
8259
        $embed          = $module.find(selector.embed),
8260
8261
        element         = this,
8262
        instance        = $module.data(moduleNamespace),
8263
        module
8264
      ;
8265
8266
      module = {
8267
8268
        initialize: function() {
8269
          module.debug('Initializing embed');
8270
          module.determine.autoplay();
8271
          module.create();
8272
          module.bind.events();
8273
          module.instantiate();
8274
        },
8275
8276
        instantiate: function() {
8277
          module.verbose('Storing instance of module', module);
8278
          instance = module;
8279
          $module
8280
            .data(moduleNamespace, module)
8281
          ;
8282
        },
8283
8284
        destroy: function() {
8285
          module.verbose('Destroying previous instance of embed');
8286
          module.reset();
8287
          $module
8288
            .removeData(moduleNamespace)
8289
            .off(eventNamespace)
8290
          ;
8291
        },
8292
8293
        refresh: function() {
8294
          module.verbose('Refreshing selector cache');
8295
          $placeholder = $module.find(selector.placeholder);
0 ignored issues
show
Unused Code introduced by
The variable $placeholder seems to be never used. Consider removing it.
Loading history...
8296
          $icon        = $module.find(selector.icon);
0 ignored issues
show
Unused Code introduced by
The variable $icon seems to be never used. Consider removing it.
Loading history...
8297
          $embed       = $module.find(selector.embed);
8298
        },
8299
8300
        bind: {
8301
          events: function() {
8302
            if( module.has.placeholder() ) {
8303
              module.debug('Adding placeholder events');
8304
              $module
8305
                .on('click' + eventNamespace, selector.placeholder, module.createAndShow)
8306
                .on('click' + eventNamespace, selector.icon, module.createAndShow)
8307
              ;
8308
            }
8309
          }
8310
        },
8311
8312
        create: function() {
8313
          var
8314
            placeholder = module.get.placeholder()
8315
          ;
8316
          if(placeholder) {
8317
            module.createPlaceholder();
8318
          }
8319
          else {
8320
            module.createAndShow();
8321
          }
8322
        },
8323
8324
        createPlaceholder: function(placeholder) {
8325
          var
8326
            icon  = module.get.icon(),
8327
            url   = module.get.url(),
8328
            embed = module.generate.embed(url)
0 ignored issues
show
Unused Code introduced by
The assignment to variable embed seems to be never used. Consider removing it.
Loading history...
8329
          ;
8330
          placeholder = placeholder || module.get.placeholder();
8331
          $module.html( templates.placeholder(placeholder, icon) );
8332
          module.debug('Creating placeholder for embed', placeholder, icon);
8333
        },
8334
8335
        createEmbed: function(url) {
8336
          module.refresh();
8337
          url = url || module.get.url();
8338
          $embed = $('<div/>')
8339
            .addClass(className.embed)
8340
            .html( module.generate.embed(url) )
8341
            .appendTo($module)
8342
          ;
8343
          settings.onCreate.call(element, url);
8344
          module.debug('Creating embed object', $embed);
8345
        },
8346
8347
        changeEmbed: function(url) {
8348
          $embed
8349
            .html( module.generate.embed(url) )
8350
          ;
8351
        },
8352
8353
        createAndShow: function() {
8354
          module.createEmbed();
8355
          module.show();
8356
        },
8357
8358
        // sets new embed
8359
        change: function(source, id, url) {
8360
          module.debug('Changing video to ', source, id, url);
8361
          $module
8362
            .data(metadata.source, source)
8363
            .data(metadata.id, id)
8364
          ;
8365
          if(url) {
8366
            $module.data(metadata.url, url);
8367
          }
8368
          else {
8369
            $module.removeData(metadata.url);
8370
          }
8371
          if(module.has.embed()) {
8372
            module.changeEmbed();
8373
          }
8374
          else {
8375
            module.create();
8376
          }
8377
        },
8378
8379
        // clears embed
8380
        reset: function() {
8381
          module.debug('Clearing embed and showing placeholder');
8382
          module.remove.active();
8383
          module.remove.embed();
8384
          module.showPlaceholder();
8385
          settings.onReset.call(element);
8386
        },
8387
8388
        // shows current embed
8389
        show: function() {
8390
          module.debug('Showing embed');
8391
          module.set.active();
8392
          settings.onDisplay.call(element);
8393
        },
8394
8395
        hide: function() {
8396
          module.debug('Hiding embed');
8397
          module.showPlaceholder();
8398
        },
8399
8400
        showPlaceholder: function() {
8401
          module.debug('Showing placeholder image');
8402
          module.remove.active();
8403
          settings.onPlaceholderDisplay.call(element);
8404
        },
8405
8406
        get: {
8407
          id: function() {
8408
            return settings.id || $module.data(metadata.id);
8409
          },
8410
          placeholder: function() {
8411
            return settings.placeholder || $module.data(metadata.placeholder);
8412
          },
8413
          icon: function() {
8414
            return (settings.icon)
8415
              ? settings.icon
8416
              : ($module.data(metadata.icon) !== undefined)
8417
                ? $module.data(metadata.icon)
8418
                : module.determine.icon()
8419
            ;
8420
          },
8421
          source: function(url) {
0 ignored issues
show
Unused Code introduced by
The parameter url is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
8422
            return (settings.source)
8423
              ? settings.source
8424
              : ($module.data(metadata.source) !== undefined)
8425
                ? $module.data(metadata.source)
8426
                : module.determine.source()
8427
            ;
8428
          },
8429
          type: function() {
8430
            var source = module.get.source();
8431
            return (sources[source] !== undefined)
8432
              ? sources[source].type
8433
              : false
8434
            ;
8435
          },
8436
          url: function() {
8437
            return (settings.url)
8438
              ? settings.url
8439
              : ($module.data(metadata.url) !== undefined)
8440
                ? $module.data(metadata.url)
8441
                : module.determine.url()
8442
            ;
8443
          }
8444
        },
8445
8446
        determine: {
8447
          autoplay: function() {
8448
            if(module.should.autoplay()) {
8449
              settings.autoplay = true;
8450
            }
8451
          },
8452
          source: function(url) {
8453
            var
8454
              matchedSource = false
8455
            ;
8456
            url = url || module.get.url();
8457
            if(url) {
8458
              $.each(sources, function(name, source) {
8459
                if(url.search(source.domain) !== -1) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if url.search(source.domain) !== -1 is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
8460
                  matchedSource = name;
8461
                  return false;
8462
                }
8463
              });
8464
            }
8465
            return matchedSource;
8466
          },
8467
          icon: function() {
8468
            var
8469
              source = module.get.source()
8470
            ;
8471
            return (sources[source] !== undefined)
8472
              ? sources[source].icon
8473
              : false
8474
            ;
8475
          },
8476
          url: function() {
8477
            var
8478
              id     = settings.id     || $module.data(metadata.id),
8479
              source = settings.source || $module.data(metadata.source),
8480
              url
8481
            ;
8482
            url = (sources[source] !== undefined)
8483
              ? sources[source].url.replace('{id}', id)
8484
              : false
8485
            ;
8486
            if(url) {
8487
              $module.data(metadata.url, url);
8488
            }
8489
            return url;
8490
          }
8491
        },
8492
8493
8494
        set: {
8495
          active: function() {
8496
            $module.addClass(className.active);
8497
          }
8498
        },
8499
8500
        remove: {
8501
          active: function() {
8502
            $module.removeClass(className.active);
8503
          },
8504
          embed: function() {
8505
            $embed.empty();
8506
          }
8507
        },
8508
8509
        encode: {
8510
          parameters: function(parameters) {
8511
            var
8512
              urlString = [],
8513
              index
8514
            ;
8515
            for (index in parameters) {
8516
              urlString.push( encodeURIComponent(index) + '=' + encodeURIComponent( parameters[index] ) );
8517
            }
8518
            return urlString.join('&amp;');
8519
          }
8520
        },
8521
8522
        generate: {
8523
          embed: function(url) {
8524
            module.debug('Generating embed html');
8525
            var
8526
              source = module.get.source(),
8527
              html,
8528
              parameters
8529
            ;
8530
            url = module.get.url(url);
8531
            if(url) {
8532
              parameters = module.generate.parameters(source);
8533
              html       = templates.iframe(url, parameters);
8534
            }
8535
            else {
8536
              module.error(error.noURL, $module);
8537
            }
8538
            return html;
0 ignored issues
show
Bug introduced by
The variable html seems to not be initialized for all possible execution paths.
Loading history...
8539
          },
8540
          parameters: function(source, extraParameters) {
8541
            var
8542
              parameters = (sources[source] && sources[source].parameters !== undefined)
8543
                ? sources[source].parameters(settings)
8544
                : {}
8545
            ;
8546
            extraParameters = extraParameters || settings.parameters;
8547
            if(extraParameters) {
8548
              parameters = $.extend({}, parameters, extraParameters);
8549
            }
8550
            parameters = settings.onEmbed(parameters);
8551
            return module.encode.parameters(parameters);
8552
          }
8553
        },
8554
8555
        has: {
8556
          embed: function() {
8557
            return ($embed.length > 0);
8558
          },
8559
          placeholder: function() {
8560
            return settings.placeholder || $module.data(metadata.placeholder);
8561
          }
8562
        },
8563
8564
        should: {
8565
          autoplay: function() {
8566
            return (settings.autoplay === 'auto')
8567
              ? (settings.placeholder || $module.data(metadata.placeholder) !== undefined)
8568
              : settings.autoplay
8569
            ;
8570
          }
8571
        },
8572
8573
        is: {
8574
          video: function() {
8575
            return module.get.type() == 'video';
8576
          }
8577
        },
8578
8579
        setting: function(name, value) {
8580
          module.debug('Changing setting', name, value);
8581
          if( $.isPlainObject(name) ) {
8582
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
8583
          }
8584
          else if(value !== undefined) {
8585
            if($.isPlainObject(settings[name])) {
8586
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
8587
            }
8588
            else {
8589
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
8590
            }
8591
          }
8592
          else {
8593
            return settings[name];
8594
          }
8595
        },
8596
        internal: function(name, value) {
8597
          if( $.isPlainObject(name) ) {
8598
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
8599
          }
8600
          else if(value !== undefined) {
8601
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
8602
          }
8603
          else {
8604
            return module[name];
8605
          }
8606
        },
8607
        debug: function() {
8608
          if(!settings.silent && settings.debug) {
8609
            if(settings.performance) {
8610
              module.performance.log(arguments);
8611
            }
8612
            else {
8613
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
8614
              module.debug.apply(console, arguments);
8615
            }
8616
          }
8617
        },
8618
        verbose: function() {
8619
          if(!settings.silent && settings.verbose && settings.debug) {
8620
            if(settings.performance) {
8621
              module.performance.log(arguments);
8622
            }
8623
            else {
8624
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
8625
              module.verbose.apply(console, arguments);
8626
            }
8627
          }
8628
        },
8629
        error: function() {
8630
          if(!settings.silent) {
8631
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
8632
            module.error.apply(console, arguments);
8633
          }
8634
        },
8635
        performance: {
8636
          log: function(message) {
8637
            var
8638
              currentTime,
8639
              executionTime,
8640
              previousTime
8641
            ;
8642
            if(settings.performance) {
8643
              currentTime   = new Date().getTime();
8644
              previousTime  = time || currentTime;
8645
              executionTime = currentTime - previousTime;
8646
              time          = currentTime;
8647
              performance.push({
8648
                'Name'           : message[0],
8649
                'Arguments'      : [].slice.call(message, 1) || '',
8650
                'Element'        : element,
8651
                'Execution Time' : executionTime
8652
              });
8653
            }
8654
            clearTimeout(module.performance.timer);
8655
            module.performance.timer = setTimeout(module.performance.display, 500);
8656
          },
8657
          display: function() {
8658
            var
8659
              title = settings.name + ':',
8660
              totalTime = 0
8661
            ;
8662
            time = false;
8663
            clearTimeout(module.performance.timer);
8664
            $.each(performance, function(index, data) {
8665
              totalTime += data['Execution Time'];
8666
            });
8667
            title += ' ' + totalTime + 'ms';
8668
            if(moduleSelector) {
8669
              title += ' \'' + moduleSelector + '\'';
8670
            }
8671
            if($allModules.length > 1) {
8672
              title += ' ' + '(' + $allModules.length + ')';
8673
            }
8674
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
8675
              console.groupCollapsed(title);
8676
              if(console.table) {
8677
                console.table(performance);
8678
              }
8679
              else {
8680
                $.each(performance, function(index, data) {
8681
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
8682
                });
8683
              }
8684
              console.groupEnd();
8685
            }
8686
            performance = [];
8687
          }
8688
        },
8689
        invoke: function(query, passedArguments, context) {
8690
          var
8691
            object = instance,
8692
            maxDepth,
8693
            found,
8694
            response
8695
          ;
8696
          passedArguments = passedArguments || queryArguments;
8697
          context         = element         || context;
8698
          if(typeof query == 'string' && object !== undefined) {
8699
            query    = query.split(/[\. ]/);
8700
            maxDepth = query.length - 1;
8701
            $.each(query, function(depth, value) {
8702
              var camelCaseValue = (depth != maxDepth)
8703
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
8704
                : query
8705
              ;
8706
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
8707
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
8708
              }
8709
              else if( object[camelCaseValue] !== undefined ) {
8710
                found = object[camelCaseValue];
8711
                return false;
8712
              }
8713
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
8714
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
8715
              }
8716
              else if( object[value] !== undefined ) {
8717
                found = object[value];
8718
                return false;
8719
              }
8720
              else {
8721
                module.error(error.method, query);
8722
                return false;
8723
              }
8724
            });
8725
          }
8726
          if ( $.isFunction( found ) ) {
8727
            response = found.apply(context, passedArguments);
8728
          }
8729
          else if(found !== undefined) {
8730
            response = found;
8731
          }
8732
          if($.isArray(returnedValue)) {
8733
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 8729 is false. Are you sure the function push handles undefined variables?
Loading history...
8734
          }
8735
          else if(returnedValue !== undefined) {
8736
            returnedValue = [returnedValue, response];
8737
          }
8738
          else if(response !== undefined) {
8739
            returnedValue = response;
8740
          }
8741
          return found;
8742
        }
8743
      };
8744
8745
      if(methodInvoked) {
8746
        if(instance === undefined) {
8747
          module.initialize();
8748
        }
8749
        module.invoke(query);
8750
      }
8751
      else {
8752
        if(instance !== undefined) {
8753
          instance.invoke('destroy');
8754
        }
8755
        module.initialize();
8756
      }
8757
    })
8758
  ;
8759
  return (returnedValue !== undefined)
8760
    ? returnedValue
8761
    : this
8762
  ;
8763
};
8764
8765
$.fn.embed.settings = {
8766
8767
  name        : 'Embed',
8768
  namespace   : 'embed',
8769
8770
  silent      : false,
8771
  debug       : false,
8772
  verbose     : false,
8773
  performance : true,
8774
8775
  icon     : false,
8776
  source   : false,
8777
  url      : false,
8778
  id       : false,
8779
8780
  // standard video settings
8781
  autoplay  : 'auto',
8782
  color     : '#444444',
8783
  hd        : true,
8784
  brandedUI : false,
8785
8786
  // additional parameters to include with the embed
8787
  parameters: false,
8788
8789
  onDisplay            : function() {},
8790
  onPlaceholderDisplay : function() {},
8791
  onReset              : function() {},
8792
  onCreate             : function(url) {},
0 ignored issues
show
Unused Code introduced by
The parameter url is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
8793
  onEmbed              : function(parameters) {
8794
    return parameters;
8795
  },
8796
8797
  metadata    : {
8798
    id          : 'id',
8799
    icon        : 'icon',
8800
    placeholder : 'placeholder',
8801
    source      : 'source',
8802
    url         : 'url'
8803
  },
8804
8805
  error : {
8806
    noURL  : 'No URL specified',
8807
    method : 'The method you called is not defined'
8808
  },
8809
8810
  className : {
8811
    active : 'active',
8812
    embed  : 'embed'
8813
  },
8814
8815
  selector : {
8816
    embed       : '.embed',
8817
    placeholder : '.placeholder',
8818
    icon        : '.icon'
8819
  },
8820
8821
  sources: {
8822
    youtube: {
8823
      name   : 'youtube',
8824
      type   : 'video',
8825
      icon   : 'video play',
8826
      domain : 'youtube.com',
8827
      url    : '//www.youtube.com/embed/{id}',
8828
      parameters: function(settings) {
8829
        return {
8830
          autohide       : !settings.brandedUI,
8831
          autoplay       : settings.autoplay,
8832
          color          : settings.color || undefined,
8833
          hq             : settings.hd,
8834
          jsapi          : settings.api,
8835
          modestbranding : !settings.brandedUI
8836
        };
8837
      }
8838
    },
8839
    vimeo: {
8840
      name   : 'vimeo',
8841
      type   : 'video',
8842
      icon   : 'video play',
8843
      domain : 'vimeo.com',
8844
      url    : '//player.vimeo.com/video/{id}',
8845
      parameters: function(settings) {
8846
        return {
8847
          api      : settings.api,
8848
          autoplay : settings.autoplay,
8849
          byline   : settings.brandedUI,
8850
          color    : settings.color || undefined,
8851
          portrait : settings.brandedUI,
8852
          title    : settings.brandedUI
8853
        };
8854
      }
8855
    }
8856
  },
8857
8858
  templates: {
8859
    iframe : function(url, parameters) {
8860
      var src = url;
8861
      if (parameters) {
8862
          src += '?' + parameters;
8863
      }
8864
      return ''
8865
        + '<iframe src="' + src + '"'
8866
        + ' width="100%" height="100%"'
8867
        + ' frameborder="0" scrolling="no" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>'
8868
      ;
8869
    },
8870
    placeholder : function(image, icon) {
8871
      var
8872
        html = ''
8873
      ;
8874
      if(icon) {
8875
        html += '<i class="' + icon + ' icon"></i>';
8876
      }
8877
      if(image) {
8878
        html += '<img class="placeholder" src="' + image + '">';
8879
      }
8880
      return html;
8881
    }
8882
  },
8883
8884
  // NOT YET IMPLEMENTED
8885
  api     : false,
8886
  onPause : function() {},
8887
  onPlay  : function() {},
8888
  onStop  : function() {}
8889
8890
};
8891
8892
8893
8894
})( jQuery, window, document );
8895
8896
/*!
8897
 * # Semantic UI 2.2.11 - Modal
8898
 * http://github.com/semantic-org/semantic-ui/
8899
 *
8900
 *
8901
 * Released under the MIT license
8902
 * http://opensource.org/licenses/MIT
8903
 *
8904
 */
8905
8906 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
8907
8908
"use strict";
8909
8910
window = (typeof window != 'undefined' && window.Math == Math)
8911
  ? window
8912
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
8913
    ? self
8914
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
8915
;
8916
8917
$.fn.modal = function(parameters) {
8918
  var
8919
    $allModules    = $(this),
8920
    $window        = $(window),
8921
    $document      = $(document),
8922
    $body          = $('body'),
8923
8924
    moduleSelector = $allModules.selector || '',
8925
8926
    time           = new Date().getTime(),
8927
    performance    = [],
8928
8929
    query          = arguments[0],
8930
    methodInvoked  = (typeof query == 'string'),
8931
    queryArguments = [].slice.call(arguments, 1),
8932
8933
    requestAnimationFrame = window.requestAnimationFrame
8934
      || window.mozRequestAnimationFrame
8935
      || window.webkitRequestAnimationFrame
8936
      || window.msRequestAnimationFrame
8937
      || function(callback) { setTimeout(callback, 0); },
8938
8939
    returnedValue
8940
  ;
8941
8942
  $allModules
8943
    .each(function() {
8944
      var
8945
        settings    = ( $.isPlainObject(parameters) )
8946
          ? $.extend(true, {}, $.fn.modal.settings, parameters)
8947
          : $.extend({}, $.fn.modal.settings),
8948
8949
        selector        = settings.selector,
8950
        className       = settings.className,
8951
        namespace       = settings.namespace,
8952
        error           = settings.error,
8953
8954
        eventNamespace  = '.' + namespace,
8955
        moduleNamespace = 'module-' + namespace,
8956
8957
        $module         = $(this),
8958
        $context        = $(settings.context),
8959
        $close          = $module.find(selector.close),
8960
8961
        $allModals,
8962
        $otherModals,
8963
        $focusedElement,
8964
        $dimmable,
8965
        $dimmer,
8966
8967
        element         = this,
8968
        instance        = $module.data(moduleNamespace),
8969
8970
        ignoreRepeatedEvents = false,
8971
8972
        elementEventNamespace,
8973
        id,
8974
        observer,
8975
        module
8976
      ;
8977
      module  = {
8978
8979
        initialize: function() {
8980
          module.verbose('Initializing dimmer', $context);
8981
8982
          module.create.id();
8983
          module.create.dimmer();
8984
          module.refreshModals();
8985
8986
          module.bind.events();
8987
          if(settings.observeChanges) {
8988
            module.observeChanges();
8989
          }
8990
          module.instantiate();
8991
        },
8992
8993
        instantiate: function() {
8994
          module.verbose('Storing instance of modal');
8995
          instance = module;
8996
          $module
8997
            .data(moduleNamespace, instance)
8998
          ;
8999
        },
9000
9001
        create: {
9002
          dimmer: function() {
9003
            var
9004
              defaultSettings = {
9005
                debug      : settings.debug,
9006
                dimmerName : 'modals'
9007
              },
9008
              dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings)
9009
            ;
9010
            if($.fn.dimmer === undefined) {
9011
              module.error(error.dimmer);
9012
              return;
9013
            }
9014
            module.debug('Creating dimmer');
9015
            $dimmable = $context.dimmer(dimmerSettings);
9016
            if(settings.detachable) {
9017
              module.verbose('Modal is detachable, moving content into dimmer');
9018
              $dimmable.dimmer('add content', $module);
9019
            }
9020
            else {
9021
              module.set.undetached();
9022
            }
9023
            $dimmer = $dimmable.dimmer('get dimmer');
9024
          },
9025
          id: function() {
9026
            id = (Math.random().toString(16) + '000000000').substr(2,8);
9027
            elementEventNamespace = '.' + id;
9028
            module.verbose('Creating unique id for element', id);
9029
          }
9030
        },
9031
9032
        destroy: function() {
9033
          module.verbose('Destroying previous modal');
9034
          $module
9035
            .removeData(moduleNamespace)
9036
            .off(eventNamespace)
9037
          ;
9038
          $window.off(elementEventNamespace);
9039
          $dimmer.off(elementEventNamespace);
9040
          $close.off(eventNamespace);
9041
          $context.dimmer('destroy');
9042
        },
9043
9044
        observeChanges: function() {
9045
          if('MutationObserver' in window) {
9046
            observer = new MutationObserver(function(mutations) {
0 ignored issues
show
Unused Code introduced by
The parameter mutations is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Bug introduced by
The variable MutationObserver seems to be never declared. If this is a global, consider adding a /** global: MutationObserver */ 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...
9047
              module.debug('DOM tree modified, refreshing');
9048
              module.refresh();
9049
            });
9050
            observer.observe(element, {
9051
              childList : true,
9052
              subtree   : true
9053
            });
9054
            module.debug('Setting up mutation observer', observer);
9055
          }
9056
        },
9057
9058
        refresh: function() {
9059
          module.remove.scrolling();
9060
          module.cacheSizes();
9061
          module.set.screenHeight();
9062
          module.set.type();
9063
          module.set.position();
9064
        },
9065
9066
        refreshModals: function() {
9067
          $otherModals = $module.siblings(selector.modal);
9068
          $allModals   = $otherModals.add($module);
9069
        },
9070
9071
        attachEvents: function(selector, event) {
9072
          var
9073
            $toggle = $(selector)
9074
          ;
9075
          event = $.isFunction(module[event])
9076
            ? module[event]
9077
            : module.toggle
9078
          ;
9079
          if($toggle.length > 0) {
9080
            module.debug('Attaching modal events to element', selector, event);
9081
            $toggle
9082
              .off(eventNamespace)
9083
              .on('click' + eventNamespace, event)
9084
            ;
9085
          }
9086
          else {
9087
            module.error(error.notFound, selector);
9088
          }
9089
        },
9090
9091
        bind: {
9092
          events: function() {
9093
            module.verbose('Attaching events');
9094
            $module
9095
              .on('click' + eventNamespace, selector.close, module.event.close)
9096
              .on('click' + eventNamespace, selector.approve, module.event.approve)
9097
              .on('click' + eventNamespace, selector.deny, module.event.deny)
9098
            ;
9099
            $window
9100
              .on('resize' + elementEventNamespace, module.event.resize)
9101
            ;
9102
          }
9103
        },
9104
9105
        get: {
9106
          id: function() {
9107
            return (Math.random().toString(16) + '000000000').substr(2,8);
9108
          }
9109
        },
9110
9111
        event: {
9112
          approve: function() {
9113
            if(ignoreRepeatedEvents || settings.onApprove.call(element, $(this)) === false) {
9114
              module.verbose('Approve callback returned false cancelling hide');
9115
              return;
9116
            }
9117
            ignoreRepeatedEvents = true;
9118
            module.hide(function() {
9119
              ignoreRepeatedEvents = false;
9120
            });
9121
          },
9122
          deny: function() {
9123
            if(ignoreRepeatedEvents || settings.onDeny.call(element, $(this)) === false) {
9124
              module.verbose('Deny callback returned false cancelling hide');
9125
              return;
9126
            }
9127
            ignoreRepeatedEvents = true;
9128
            module.hide(function() {
9129
              ignoreRepeatedEvents = false;
9130
            });
9131
          },
9132
          close: function() {
9133
            module.hide();
9134
          },
9135
          click: function(event) {
9136
            var
9137
              $target   = $(event.target),
9138
              isInModal = ($target.closest(selector.modal).length > 0),
9139
              isInDOM   = $.contains(document.documentElement, event.target)
9140
            ;
9141
            if(!isInModal && isInDOM) {
9142
              module.debug('Dimmer clicked, hiding all modals');
9143
              if( module.is.active() ) {
9144
                module.remove.clickaway();
9145
                if(settings.allowMultiple) {
9146
                  module.hide();
9147
                }
9148
                else {
9149
                  module.hideAll();
9150
                }
9151
              }
9152
            }
9153
          },
9154
          debounce: function(method, delay) {
9155
            clearTimeout(module.timer);
9156
            module.timer = setTimeout(method, delay);
9157
          },
9158
          keyboard: function(event) {
9159
            var
9160
              keyCode   = event.which,
9161
              escapeKey = 27
9162
            ;
9163
            if(keyCode == escapeKey) {
9164
              if(settings.closable) {
9165
                module.debug('Escape key pressed hiding modal');
9166
                module.hide();
9167
              }
9168
              else {
9169
                module.debug('Escape key pressed, but closable is set to false');
9170
              }
9171
              event.preventDefault();
9172
            }
9173
          },
9174
          resize: function() {
9175
            if( $dimmable.dimmer('is active') && ( module.is.animating() || module.is.active() ) ) {
9176
              requestAnimationFrame(module.refresh);
9177
            }
9178
          }
9179
        },
9180
9181
        toggle: function() {
9182
          if( module.is.active() || module.is.animating() ) {
9183
            module.hide();
9184
          }
9185
          else {
9186
            module.show();
9187
          }
9188
        },
9189
9190
        show: function(callback) {
9191
          callback = $.isFunction(callback)
9192
            ? callback
9193
            : function(){}
9194
          ;
9195
          module.refreshModals();
9196
          module.set.dimmerSettings();
9197
          module.showModal(callback);
9198
        },
9199
9200
        hide: function(callback) {
9201
          callback = $.isFunction(callback)
9202
            ? callback
9203
            : function(){}
9204
          ;
9205
          module.refreshModals();
9206
          module.hideModal(callback);
9207
        },
9208
9209
        showModal: function(callback) {
9210
          callback = $.isFunction(callback)
9211
            ? callback
9212
            : function(){}
9213
          ;
9214
          if( module.is.animating() || !module.is.active() ) {
9215
9216
            module.showDimmer();
9217
            module.cacheSizes();
9218
            module.set.position();
9219
            module.set.screenHeight();
9220
            module.set.type();
9221
            module.set.clickaway();
9222
9223
            if( !settings.allowMultiple && module.others.active() ) {
9224
              module.hideOthers(module.showModal);
9225
            }
9226
            else {
9227
              settings.onShow.call(element);
9228
              if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
9229
                module.debug('Showing modal with css animations');
9230
                $module
9231
                  .transition({
9232
                    debug       : settings.debug,
9233
                    animation   : settings.transition + ' in',
9234
                    queue       : settings.queue,
9235
                    duration    : settings.duration,
9236
                    useFailSafe : true,
9237
                    onComplete : function() {
9238
                      settings.onVisible.apply(element);
9239
                      if(settings.keyboardShortcuts) {
9240
                        module.add.keyboardShortcuts();
9241
                      }
9242
                      module.save.focus();
9243
                      module.set.active();
9244
                      if(settings.autofocus) {
9245
                        module.set.autofocus();
9246
                      }
9247
                      callback();
9248
                    }
9249
                  })
9250
                ;
9251
              }
9252
              else {
9253
                module.error(error.noTransition);
9254
              }
9255
            }
9256
          }
9257
          else {
9258
            module.debug('Modal is already visible');
9259
          }
9260
        },
9261
9262
        hideModal: function(callback, keepDimmed) {
9263
          callback = $.isFunction(callback)
9264
            ? callback
9265
            : function(){}
9266
          ;
9267
          module.debug('Hiding modal');
9268
          if(settings.onHide.call(element, $(this)) === false) {
9269
            module.verbose('Hide callback returned false cancelling hide');
9270
            return;
9271
          }
9272
9273
          if( module.is.animating() || module.is.active() ) {
9274
            if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
9275
              module.remove.active();
9276
              $module
9277
                .transition({
9278
                  debug       : settings.debug,
9279
                  animation   : settings.transition + ' out',
9280
                  queue       : settings.queue,
9281
                  duration    : settings.duration,
9282
                  useFailSafe : true,
9283
                  onStart     : function() {
9284
                    if(!module.others.active() && !keepDimmed) {
9285
                      module.hideDimmer();
9286
                    }
9287
                    if(settings.keyboardShortcuts) {
9288
                      module.remove.keyboardShortcuts();
9289
                    }
9290
                  },
9291
                  onComplete : function() {
9292
                    settings.onHidden.call(element);
9293
                    module.restore.focus();
9294
                    callback();
9295
                  }
9296
                })
9297
              ;
9298
            }
9299
            else {
9300
              module.error(error.noTransition);
9301
            }
9302
          }
9303
        },
9304
9305
        showDimmer: function() {
9306
          if($dimmable.dimmer('is animating') || !$dimmable.dimmer('is active') ) {
9307
            module.debug('Showing dimmer');
9308
            $dimmable.dimmer('show');
9309
          }
9310
          else {
9311
            module.debug('Dimmer already visible');
9312
          }
9313
        },
9314
9315
        hideDimmer: function() {
9316
          if( $dimmable.dimmer('is animating') || ($dimmable.dimmer('is active')) ) {
9317
            $dimmable.dimmer('hide', function() {
9318
              module.remove.clickaway();
9319
              module.remove.screenHeight();
9320
            });
9321
          }
9322
          else {
9323
            module.debug('Dimmer is not visible cannot hide');
9324
            return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
9325
          }
9326
        },
9327
9328
        hideAll: function(callback) {
9329
          var
9330
            $visibleModals = $allModals.filter('.' + className.active + ', .' + className.animating)
9331
          ;
9332
          callback = $.isFunction(callback)
9333
            ? callback
9334
            : function(){}
9335
          ;
9336
          if( $visibleModals.length > 0 ) {
9337
            module.debug('Hiding all visible modals');
9338
            module.hideDimmer();
9339
            $visibleModals
9340
              .modal('hide modal', callback)
9341
            ;
9342
          }
9343
        },
9344
9345
        hideOthers: function(callback) {
9346
          var
9347
            $visibleModals = $otherModals.filter('.' + className.active + ', .' + className.animating)
9348
          ;
9349
          callback = $.isFunction(callback)
9350
            ? callback
9351
            : function(){}
9352
          ;
9353
          if( $visibleModals.length > 0 ) {
9354
            module.debug('Hiding other modals', $otherModals);
9355
            $visibleModals
9356
              .modal('hide modal', callback, true)
9357
            ;
9358
          }
9359
        },
9360
9361
        others: {
9362
          active: function() {
9363
            return ($otherModals.filter('.' + className.active).length > 0);
9364
          },
9365
          animating: function() {
9366
            return ($otherModals.filter('.' + className.animating).length > 0);
9367
          }
9368
        },
9369
9370
9371
        add: {
9372
          keyboardShortcuts: function() {
9373
            module.verbose('Adding keyboard shortcuts');
9374
            $document
9375
              .on('keyup' + eventNamespace, module.event.keyboard)
9376
            ;
9377
          }
9378
        },
9379
9380
        save: {
9381
          focus: function() {
9382
            $focusedElement = $(document.activeElement).blur();
9383
          }
9384
        },
9385
9386
        restore: {
9387
          focus: function() {
9388
            if($focusedElement && $focusedElement.length > 0) {
9389
              $focusedElement.focus();
9390
            }
9391
          }
9392
        },
9393
9394
        remove: {
9395
          active: function() {
9396
            $module.removeClass(className.active);
9397
          },
9398
          clickaway: function() {
9399
            if(settings.closable) {
9400
              $dimmer
9401
                .off('click' + elementEventNamespace)
9402
              ;
9403
            }
9404
          },
9405
          bodyStyle: function() {
9406
            if($body.attr('style') === '') {
9407
              module.verbose('Removing style attribute');
9408
              $body.removeAttr('style');
9409
            }
9410
          },
9411
          screenHeight: function() {
9412
            module.debug('Removing page height');
9413
            $body
9414
              .css('height', '')
9415
            ;
9416
          },
9417
          keyboardShortcuts: function() {
9418
            module.verbose('Removing keyboard shortcuts');
9419
            $document
9420
              .off('keyup' + eventNamespace)
9421
            ;
9422
          },
9423
          scrolling: function() {
9424
            $dimmable.removeClass(className.scrolling);
9425
            $module.removeClass(className.scrolling);
9426
          }
9427
        },
9428
9429
        cacheSizes: function() {
9430
          var
9431
            modalHeight = $module.outerHeight()
9432
          ;
9433
          if(module.cache === undefined || modalHeight !== 0) {
9434
            module.cache = {
9435
              pageHeight    : $(document).outerHeight(),
9436
              height        : modalHeight + settings.offset,
9437
              contextHeight : (settings.context == 'body')
9438
                ? $(window).height()
9439
                : $dimmable.height()
9440
            };
9441
          }
9442
          module.debug('Caching modal and container sizes', module.cache);
9443
        },
9444
9445
        can: {
9446
          fit: function() {
9447
            return ( ( module.cache.height + (settings.padding * 2) ) < module.cache.contextHeight);
9448
          }
9449
        },
9450
9451
        is: {
9452
          active: function() {
9453
            return $module.hasClass(className.active);
9454
          },
9455
          animating: function() {
9456
            return $module.transition('is supported')
9457
              ? $module.transition('is animating')
9458
              : $module.is(':visible')
9459
            ;
9460
          },
9461
          scrolling: function() {
9462
            return $dimmable.hasClass(className.scrolling);
9463
          },
9464
          modernBrowser: function() {
9465
            // appName for IE11 reports 'Netscape' can no longer use
9466
            return !(window.ActiveXObject || "ActiveXObject" in window);
9467
          }
9468
        },
9469
9470
        set: {
9471
          autofocus: function() {
9472
            var
9473
              $inputs    = $module.find('[tabindex], :input').filter(':visible'),
9474
              $autofocus = $inputs.filter('[autofocus]'),
9475
              $input     = ($autofocus.length > 0)
9476
                ? $autofocus.first()
9477
                : $inputs.first()
9478
            ;
9479
            if($input.length > 0) {
9480
              $input.focus();
9481
            }
9482
          },
9483
          clickaway: function() {
9484
            if(settings.closable) {
9485
              $dimmer
9486
                .on('click' + elementEventNamespace, module.event.click)
9487
              ;
9488
            }
9489
          },
9490
          dimmerSettings: function() {
9491
            if($.fn.dimmer === undefined) {
9492
              module.error(error.dimmer);
9493
              return;
9494
            }
9495
            var
9496
              defaultSettings = {
9497
                debug      : settings.debug,
9498
                dimmerName : 'modals',
9499
                variation  : false,
9500
                closable   : 'auto',
9501
                duration   : {
9502
                  show     : settings.duration,
9503
                  hide     : settings.duration
9504
                }
9505
              },
9506
              dimmerSettings = $.extend(true, defaultSettings, settings.dimmerSettings)
9507
            ;
9508
            if(settings.inverted) {
9509
              dimmerSettings.variation = (dimmerSettings.variation !== undefined)
9510
                ? dimmerSettings.variation + ' inverted'
9511
                : 'inverted'
9512
              ;
9513
              $dimmer.addClass(className.inverted);
9514
            }
9515
            else {
9516
              $dimmer.removeClass(className.inverted);
9517
            }
9518
            if(settings.blurring) {
9519
              $dimmable.addClass(className.blurring);
9520
            }
9521
            else {
9522
              $dimmable.removeClass(className.blurring);
9523
            }
9524
            $context.dimmer('setting', dimmerSettings);
9525
          },
9526
          screenHeight: function() {
9527
            if( module.can.fit() ) {
9528
              $body.css('height', '');
9529
            }
9530
            else {
9531
              module.debug('Modal is taller than page content, resizing page height');
9532
              $body
9533
                .css('height', module.cache.height + (settings.padding * 2) )
9534
              ;
9535
            }
9536
          },
9537
          active: function() {
9538
            $module.addClass(className.active);
9539
          },
9540
          scrolling: function() {
9541
            $dimmable.addClass(className.scrolling);
9542
            $module.addClass(className.scrolling);
9543
          },
9544
          type: function() {
9545
            if(module.can.fit()) {
9546
              module.verbose('Modal fits on screen');
9547
              if(!module.others.active() && !module.others.animating()) {
9548
                module.remove.scrolling();
9549
              }
9550
            }
9551
            else {
9552
              module.verbose('Modal cannot fit on screen setting to scrolling');
9553
              module.set.scrolling();
9554
            }
9555
          },
9556
          position: function() {
9557
            module.verbose('Centering modal on page', module.cache);
9558
            if(module.can.fit()) {
9559
              $module
9560
                .css({
9561
                  top: '',
9562
                  marginTop: -(module.cache.height / 2)
9563
                })
9564
              ;
9565
            }
9566
            else {
9567
              $module
9568
                .css({
9569
                  marginTop : '',
9570
                  top       : $document.scrollTop()
9571
                })
9572
              ;
9573
            }
9574
          },
9575
          undetached: function() {
9576
            $dimmable.addClass(className.undetached);
9577
          }
9578
        },
9579
9580
        setting: function(name, value) {
9581
          module.debug('Changing setting', name, value);
9582
          if( $.isPlainObject(name) ) {
9583
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
9584
          }
9585
          else if(value !== undefined) {
9586
            if($.isPlainObject(settings[name])) {
9587
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
9588
            }
9589
            else {
9590
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
9591
            }
9592
          }
9593
          else {
9594
            return settings[name];
9595
          }
9596
        },
9597
        internal: function(name, value) {
9598
          if( $.isPlainObject(name) ) {
9599
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
9600
          }
9601
          else if(value !== undefined) {
9602
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
9603
          }
9604
          else {
9605
            return module[name];
9606
          }
9607
        },
9608
        debug: function() {
9609
          if(!settings.silent && settings.debug) {
9610
            if(settings.performance) {
9611
              module.performance.log(arguments);
9612
            }
9613
            else {
9614
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
9615
              module.debug.apply(console, arguments);
9616
            }
9617
          }
9618
        },
9619
        verbose: function() {
9620
          if(!settings.silent && settings.verbose && settings.debug) {
9621
            if(settings.performance) {
9622
              module.performance.log(arguments);
9623
            }
9624
            else {
9625
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
9626
              module.verbose.apply(console, arguments);
9627
            }
9628
          }
9629
        },
9630
        error: function() {
9631
          if(!settings.silent) {
9632
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
9633
            module.error.apply(console, arguments);
9634
          }
9635
        },
9636
        performance: {
9637
          log: function(message) {
9638
            var
9639
              currentTime,
9640
              executionTime,
9641
              previousTime
9642
            ;
9643
            if(settings.performance) {
9644
              currentTime   = new Date().getTime();
9645
              previousTime  = time || currentTime;
9646
              executionTime = currentTime - previousTime;
9647
              time          = currentTime;
9648
              performance.push({
9649
                'Name'           : message[0],
9650
                'Arguments'      : [].slice.call(message, 1) || '',
9651
                'Element'        : element,
9652
                'Execution Time' : executionTime
9653
              });
9654
            }
9655
            clearTimeout(module.performance.timer);
9656
            module.performance.timer = setTimeout(module.performance.display, 500);
9657
          },
9658
          display: function() {
9659
            var
9660
              title = settings.name + ':',
9661
              totalTime = 0
9662
            ;
9663
            time = false;
9664
            clearTimeout(module.performance.timer);
9665
            $.each(performance, function(index, data) {
9666
              totalTime += data['Execution Time'];
9667
            });
9668
            title += ' ' + totalTime + 'ms';
9669
            if(moduleSelector) {
9670
              title += ' \'' + moduleSelector + '\'';
9671
            }
9672
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
9673
              console.groupCollapsed(title);
9674
              if(console.table) {
9675
                console.table(performance);
9676
              }
9677
              else {
9678
                $.each(performance, function(index, data) {
9679
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
9680
                });
9681
              }
9682
              console.groupEnd();
9683
            }
9684
            performance = [];
9685
          }
9686
        },
9687
        invoke: function(query, passedArguments, context) {
9688
          var
9689
            object = instance,
9690
            maxDepth,
9691
            found,
9692
            response
9693
          ;
9694
          passedArguments = passedArguments || queryArguments;
9695
          context         = element         || context;
9696
          if(typeof query == 'string' && object !== undefined) {
9697
            query    = query.split(/[\. ]/);
9698
            maxDepth = query.length - 1;
9699
            $.each(query, function(depth, value) {
9700
              var camelCaseValue = (depth != maxDepth)
9701
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
9702
                : query
9703
              ;
9704
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
9705
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
9706
              }
9707
              else if( object[camelCaseValue] !== undefined ) {
9708
                found = object[camelCaseValue];
9709
                return false;
9710
              }
9711
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
9712
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
9713
              }
9714
              else if( object[value] !== undefined ) {
9715
                found = object[value];
9716
                return false;
9717
              }
9718
              else {
9719
                return false;
9720
              }
9721
            });
9722
          }
9723
          if ( $.isFunction( found ) ) {
9724
            response = found.apply(context, passedArguments);
9725
          }
9726
          else if(found !== undefined) {
9727
            response = found;
9728
          }
9729
          if($.isArray(returnedValue)) {
9730
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 9726 is false. Are you sure the function push handles undefined variables?
Loading history...
9731
          }
9732
          else if(returnedValue !== undefined) {
9733
            returnedValue = [returnedValue, response];
9734
          }
9735
          else if(response !== undefined) {
9736
            returnedValue = response;
9737
          }
9738
          return found;
9739
        }
9740
      };
9741
9742
      if(methodInvoked) {
9743
        if(instance === undefined) {
9744
          module.initialize();
9745
        }
9746
        module.invoke(query);
9747
      }
9748
      else {
9749
        if(instance !== undefined) {
9750
          instance.invoke('destroy');
9751
        }
9752
        module.initialize();
9753
      }
9754
    })
9755
  ;
9756
9757
  return (returnedValue !== undefined)
9758
    ? returnedValue
9759
    : this
9760
  ;
9761
};
9762
9763
$.fn.modal.settings = {
9764
9765
  name           : 'Modal',
9766
  namespace      : 'modal',
9767
9768
  silent         : false,
9769
  debug          : false,
9770
  verbose        : false,
9771
  performance    : true,
9772
9773
  observeChanges : false,
9774
9775
  allowMultiple  : false,
9776
  detachable     : true,
9777
  closable       : true,
9778
  autofocus      : true,
9779
9780
  inverted       : false,
9781
  blurring       : false,
9782
9783
  dimmerSettings : {
9784
    closable : false,
9785
    useCSS   : true
9786
  },
9787
9788
  // whether to use keyboard shortcuts
9789
  keyboardShortcuts: true,
9790
9791
  context    : 'body',
9792
9793
  queue      : false,
9794
  duration   : 500,
9795
  offset     : 0,
9796
  transition : 'scale',
9797
9798
  // padding with edge of page
9799
  padding    : 50,
9800
9801
  // called before show animation
9802
  onShow     : function(){},
9803
9804
  // called after show animation
9805
  onVisible  : function(){},
9806
9807
  // called before hide animation
9808
  onHide     : function(){ return true; },
9809
9810
  // called after hide animation
9811
  onHidden   : function(){},
9812
9813
  // called after approve selector match
9814
  onApprove  : function(){ return true; },
9815
9816
  // called after deny selector match
9817
  onDeny     : function(){ return true; },
9818
9819
  selector    : {
9820
    close    : '> .close',
9821
    approve  : '.actions .positive, .actions .approve, .actions .ok',
9822
    deny     : '.actions .negative, .actions .deny, .actions .cancel',
9823
    modal    : '.ui.modal'
9824
  },
9825
  error : {
9826
    dimmer    : 'UI Dimmer, a required component is not included in this page',
9827
    method    : 'The method you called is not defined.',
9828
    notFound  : 'The element you specified could not be found'
9829
  },
9830
  className : {
9831
    active     : 'active',
9832
    animating  : 'animating',
9833
    blurring   : 'blurring',
9834
    inverted   : 'inverted',
9835
    scrolling  : 'scrolling',
9836
    undetached : 'undetached'
9837
  }
9838
};
9839
9840
9841
})( jQuery, window, document );
9842
9843
/*!
9844
 * # Semantic UI 2.2.11 - Nag
9845
 * http://github.com/semantic-org/semantic-ui/
9846
 *
9847
 *
9848
 * Released under the MIT license
9849
 * http://opensource.org/licenses/MIT
9850
 *
9851
 */
9852
9853 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
9854
9855
"use strict";
9856
9857
window = (typeof window != 'undefined' && window.Math == Math)
9858
  ? window
9859
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
9860
    ? self
9861
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
9862
;
9863
9864
$.fn.nag = function(parameters) {
9865
  var
9866
    $allModules    = $(this),
9867
    moduleSelector = $allModules.selector || '',
9868
9869
    time           = new Date().getTime(),
9870
    performance    = [],
9871
9872
    query          = arguments[0],
9873
    methodInvoked  = (typeof query == 'string'),
9874
    queryArguments = [].slice.call(arguments, 1),
9875
    returnedValue
9876
  ;
9877
  $allModules
9878
    .each(function() {
9879
      var
9880
        settings          = ( $.isPlainObject(parameters) )
9881
          ? $.extend(true, {}, $.fn.nag.settings, parameters)
9882
          : $.extend({}, $.fn.nag.settings),
9883
9884
        className       = settings.className,
0 ignored issues
show
Unused Code introduced by
The assignment to variable className seems to be never used. Consider removing it.
Loading history...
9885
        selector        = settings.selector,
9886
        error           = settings.error,
9887
        namespace       = settings.namespace,
9888
9889
        eventNamespace  = '.' + namespace,
9890
        moduleNamespace = namespace + '-module',
9891
9892
        $module         = $(this),
9893
9894
        $close          = $module.find(selector.close),
0 ignored issues
show
Unused Code introduced by
The variable $close seems to be never used. Consider removing it.
Loading history...
9895
        $context        = (settings.context)
9896
          ? $(settings.context)
9897
          : $('body'),
9898
9899
        element         = this,
9900
        instance        = $module.data(moduleNamespace),
9901
9902
        moduleOffset,
0 ignored issues
show
Unused Code introduced by
The variable moduleOffset seems to be never used. Consider removing it.
Loading history...
9903
        moduleHeight,
0 ignored issues
show
Unused Code introduced by
The variable moduleHeight seems to be never used. Consider removing it.
Loading history...
9904
9905
        contextWidth,
0 ignored issues
show
Unused Code introduced by
The variable contextWidth seems to be never used. Consider removing it.
Loading history...
9906
        contextHeight,
0 ignored issues
show
Unused Code introduced by
The variable contextHeight seems to be never used. Consider removing it.
Loading history...
9907
        contextOffset,
0 ignored issues
show
Unused Code introduced by
The variable contextOffset seems to be never used. Consider removing it.
Loading history...
9908
9909
        yOffset,
0 ignored issues
show
Unused Code introduced by
The variable yOffset seems to be never used. Consider removing it.
Loading history...
9910
        yPosition,
0 ignored issues
show
Unused Code introduced by
The variable yPosition seems to be never used. Consider removing it.
Loading history...
9911
9912
        timer,
9913
        module,
9914
9915
        requestAnimationFrame = window.requestAnimationFrame
0 ignored issues
show
Unused Code introduced by
The assignment to variable requestAnimationFrame seems to be never used. Consider removing it.
Loading history...
9916
          || window.mozRequestAnimationFrame
9917
          || window.webkitRequestAnimationFrame
9918
          || window.msRequestAnimationFrame
9919
          || function(callback) { setTimeout(callback, 0); }
9920
      ;
9921
      module = {
9922
9923
        initialize: function() {
9924
          module.verbose('Initializing element');
9925
9926
          $module
9927
            .on('click' + eventNamespace, selector.close, module.dismiss)
9928
            .data(moduleNamespace, module)
9929
          ;
9930
9931
          if(settings.detachable && $module.parent()[0] !== $context[0]) {
9932
            $module
9933
              .detach()
9934
              .prependTo($context)
9935
            ;
9936
          }
9937
9938
          if(settings.displayTime > 0) {
9939
            setTimeout(module.hide, settings.displayTime);
9940
          }
9941
          module.show();
9942
        },
9943
9944
        destroy: function() {
9945
          module.verbose('Destroying instance');
9946
          $module
9947
            .removeData(moduleNamespace)
9948
            .off(eventNamespace)
9949
          ;
9950
        },
9951
9952
        show: function() {
9953
          if( module.should.show() && !$module.is(':visible') ) {
9954
            module.debug('Showing nag', settings.animation.show);
9955
            if(settings.animation.show == 'fade') {
9956
              $module
9957
                .fadeIn(settings.duration, settings.easing)
9958
              ;
9959
            }
9960
            else {
9961
              $module
9962
                .slideDown(settings.duration, settings.easing)
9963
              ;
9964
            }
9965
          }
9966
        },
9967
9968
        hide: function() {
9969
          module.debug('Showing nag', settings.animation.hide);
9970
          if(settings.animation.show == 'fade') {
9971
            $module
9972
              .fadeIn(settings.duration, settings.easing)
9973
            ;
9974
          }
9975
          else {
9976
            $module
9977
              .slideUp(settings.duration, settings.easing)
9978
            ;
9979
          }
9980
        },
9981
9982
        onHide: function() {
9983
          module.debug('Removing nag', settings.animation.hide);
9984
          $module.remove();
9985
          if (settings.onHide) {
9986
            settings.onHide();
9987
          }
9988
        },
9989
9990
        dismiss: function(event) {
9991
          if(settings.storageMethod) {
9992
            module.storage.set(settings.key, settings.value);
9993
          }
9994
          module.hide();
9995
          event.stopImmediatePropagation();
9996
          event.preventDefault();
9997
        },
9998
9999
        should: {
10000
          show: function() {
10001
            if(settings.persist) {
10002
              module.debug('Persistent nag is set, can show nag');
10003
              return true;
10004
            }
10005
            if( module.storage.get(settings.key) != settings.value.toString() ) {
10006
              module.debug('Stored value is not set, can show nag', module.storage.get(settings.key));
10007
              return true;
10008
            }
10009
            module.debug('Stored value is set, cannot show nag', module.storage.get(settings.key));
10010
            return false;
10011
          }
10012
        },
10013
10014
        get: {
10015
          storageOptions: function() {
10016
            var
10017
              options = {}
10018
            ;
10019
            if(settings.expires) {
10020
              options.expires = settings.expires;
10021
            }
10022
            if(settings.domain) {
10023
              options.domain = settings.domain;
10024
            }
10025
            if(settings.path) {
10026
              options.path = settings.path;
10027
            }
10028
            return options;
10029
          }
10030
        },
10031
10032
        clear: function() {
10033
          module.storage.remove(settings.key);
10034
        },
10035
10036
        storage: {
10037
          set: function(key, value) {
10038
            var
10039
              options = module.get.storageOptions()
10040
            ;
10041
            if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
10042
              window.localStorage.setItem(key, value);
10043
              module.debug('Value stored using local storage', key, value);
10044
            }
10045
            else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
10046
              window.sessionStorage.setItem(key, value);
10047
              module.debug('Value stored using session storage', key, value);
10048
            }
10049
            else if($.cookie !== undefined) {
10050
              $.cookie(key, value, options);
10051
              module.debug('Value stored using cookie', key, value, options);
10052
            }
10053
            else {
10054
              module.error(error.noCookieStorage);
10055
              return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
10056
            }
10057
          },
10058
          get: function(key, value) {
0 ignored issues
show
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
10059
            var
10060
              storedValue
10061
            ;
10062
            if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
10063
              storedValue = window.localStorage.getItem(key);
10064
            }
10065
            else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
10066
              storedValue = window.sessionStorage.getItem(key);
10067
            }
10068
            // get by cookie
10069
            else if($.cookie !== undefined) {
10070
              storedValue = $.cookie(key);
10071
            }
10072
            else {
10073
              module.error(error.noCookieStorage);
10074
            }
10075
            if(storedValue == 'undefined' || storedValue == 'null' || storedValue === undefined || storedValue === null) {
0 ignored issues
show
Bug introduced by
The variable storedValue seems to not be initialized for all possible execution paths.
Loading history...
10076
              storedValue = undefined;
10077
            }
10078
            return storedValue;
10079
          },
10080
          remove: function(key) {
10081
            var
10082
              options = module.get.storageOptions()
10083
            ;
10084
            if(settings.storageMethod == 'localstorage' && window.localStorage !== undefined) {
10085
              window.localStorage.removeItem(key);
10086
            }
10087
            else if(settings.storageMethod == 'sessionstorage' && window.sessionStorage !== undefined) {
10088
              window.sessionStorage.removeItem(key);
10089
            }
10090
            // store by cookie
10091
            else if($.cookie !== undefined) {
10092
              $.removeCookie(key, options);
10093
            }
10094
            else {
10095
              module.error(error.noStorage);
10096
            }
10097
          }
10098
        },
10099
10100
        setting: function(name, value) {
10101
          module.debug('Changing setting', name, value);
10102
          if( $.isPlainObject(name) ) {
10103
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
10104
          }
10105
          else if(value !== undefined) {
10106
            if($.isPlainObject(settings[name])) {
10107
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
10108
            }
10109
            else {
10110
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
10111
            }
10112
          }
10113
          else {
10114
            return settings[name];
10115
          }
10116
        },
10117
        internal: function(name, value) {
10118
          if( $.isPlainObject(name) ) {
10119
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
10120
          }
10121
          else if(value !== undefined) {
10122
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
10123
          }
10124
          else {
10125
            return module[name];
10126
          }
10127
        },
10128
        debug: function() {
10129
          if(!settings.silent && settings.debug) {
10130
            if(settings.performance) {
10131
              module.performance.log(arguments);
10132
            }
10133
            else {
10134
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
10135
              module.debug.apply(console, arguments);
10136
            }
10137
          }
10138
        },
10139
        verbose: function() {
10140
          if(!settings.silent && settings.verbose && settings.debug) {
10141
            if(settings.performance) {
10142
              module.performance.log(arguments);
10143
            }
10144
            else {
10145
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
10146
              module.verbose.apply(console, arguments);
10147
            }
10148
          }
10149
        },
10150
        error: function() {
10151
          if(!settings.silent) {
10152
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
10153
            module.error.apply(console, arguments);
10154
          }
10155
        },
10156
        performance: {
10157
          log: function(message) {
10158
            var
10159
              currentTime,
10160
              executionTime,
10161
              previousTime
10162
            ;
10163
            if(settings.performance) {
10164
              currentTime   = new Date().getTime();
10165
              previousTime  = time || currentTime;
10166
              executionTime = currentTime - previousTime;
10167
              time          = currentTime;
10168
              performance.push({
10169
                'Name'           : message[0],
10170
                'Arguments'      : [].slice.call(message, 1) || '',
10171
                'Element'        : element,
10172
                'Execution Time' : executionTime
10173
              });
10174
            }
10175
            clearTimeout(module.performance.timer);
10176
            module.performance.timer = setTimeout(module.performance.display, 500);
10177
          },
10178
          display: function() {
10179
            var
10180
              title = settings.name + ':',
10181
              totalTime = 0
10182
            ;
10183
            time = false;
10184
            clearTimeout(module.performance.timer);
10185
            $.each(performance, function(index, data) {
10186
              totalTime += data['Execution Time'];
10187
            });
10188
            title += ' ' + totalTime + 'ms';
10189
            if(moduleSelector) {
10190
              title += ' \'' + moduleSelector + '\'';
10191
            }
10192
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
10193
              console.groupCollapsed(title);
10194
              if(console.table) {
10195
                console.table(performance);
10196
              }
10197
              else {
10198
                $.each(performance, function(index, data) {
10199
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
10200
                });
10201
              }
10202
              console.groupEnd();
10203
            }
10204
            performance = [];
10205
          }
10206
        },
10207
        invoke: function(query, passedArguments, context) {
10208
          var
10209
            object = instance,
10210
            maxDepth,
10211
            found,
10212
            response
10213
          ;
10214
          passedArguments = passedArguments || queryArguments;
10215
          context         = element         || context;
10216
          if(typeof query == 'string' && object !== undefined) {
10217
            query    = query.split(/[\. ]/);
10218
            maxDepth = query.length - 1;
10219
            $.each(query, function(depth, value) {
10220
              var camelCaseValue = (depth != maxDepth)
10221
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
10222
                : query
10223
              ;
10224
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
10225
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
10226
              }
10227
              else if( object[camelCaseValue] !== undefined ) {
10228
                found = object[camelCaseValue];
10229
                return false;
10230
              }
10231
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
10232
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
10233
              }
10234
              else if( object[value] !== undefined ) {
10235
                found = object[value];
10236
                return false;
10237
              }
10238
              else {
10239
                module.error(error.method, query);
10240
                return false;
10241
              }
10242
            });
10243
          }
10244
          if ( $.isFunction( found ) ) {
10245
            response = found.apply(context, passedArguments);
10246
          }
10247
          else if(found !== undefined) {
10248
            response = found;
10249
          }
10250
          if($.isArray(returnedValue)) {
10251
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 10247 is false. Are you sure the function push handles undefined variables?
Loading history...
10252
          }
10253
          else if(returnedValue !== undefined) {
10254
            returnedValue = [returnedValue, response];
10255
          }
10256
          else if(response !== undefined) {
10257
            returnedValue = response;
10258
          }
10259
          return found;
10260
        }
10261
      };
10262
10263
      if(methodInvoked) {
10264
        if(instance === undefined) {
10265
          module.initialize();
10266
        }
10267
        module.invoke(query);
10268
      }
10269
      else {
10270
        if(instance !== undefined) {
10271
          instance.invoke('destroy');
10272
        }
10273
        module.initialize();
10274
      }
10275
    })
10276
  ;
10277
10278
  return (returnedValue !== undefined)
10279
    ? returnedValue
10280
    : this
10281
  ;
10282
};
10283
10284
$.fn.nag.settings = {
10285
10286
  name        : 'Nag',
10287
10288
  silent      : false,
10289
  debug       : false,
10290
  verbose     : false,
10291
  performance : true,
10292
10293
  namespace   : 'Nag',
10294
10295
  // allows cookie to be overridden
10296
  persist     : false,
10297
10298
  // set to zero to require manually dismissal, otherwise hides on its own
10299
  displayTime : 0,
10300
10301
  animation   : {
10302
    show : 'slide',
10303
    hide : 'slide'
10304
  },
10305
10306
  context       : false,
10307
  detachable    : false,
10308
10309
  expires       : 30,
10310
  domain        : false,
10311
  path          : '/',
10312
10313
  // type of storage to use
10314
  storageMethod : 'cookie',
10315
10316
  // value to store in dismissed localstorage/cookie
10317
  key           : 'nag',
10318
  value         : 'dismiss',
10319
10320
  error: {
10321
    noCookieStorage : '$.cookie is not included. A storage solution is required.',
10322
    noStorage       : 'Neither $.cookie or store is defined. A storage solution is required for storing state',
10323
    method          : 'The method you called is not defined.'
10324
  },
10325
10326
  className     : {
10327
    bottom : 'bottom',
10328
    fixed  : 'fixed'
10329
  },
10330
10331
  selector      : {
10332
    close : '.close.icon'
10333
  },
10334
10335
  speed         : 500,
10336
  easing        : 'easeOutQuad',
10337
10338
  onHide: function() {}
10339
10340
};
10341
10342
// Adds easing
10343
$.extend( $.easing, {
10344
  easeOutQuad: function (x, t, b, c, d) {
10345
    return -c *(t/=d)*(t-2) + b;
10346
  }
10347
});
10348
10349
})( jQuery, window, document );
10350
10351
/*!
10352
 * # Semantic UI 2.2.11 - Popup
10353
 * http://github.com/semantic-org/semantic-ui/
10354
 *
10355
 *
10356
 * Released under the MIT license
10357
 * http://opensource.org/licenses/MIT
10358
 *
10359
 */
10360
10361 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
10362
10363
"use strict";
10364
10365
window = (typeof window != 'undefined' && window.Math == Math)
10366
  ? window
10367
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
10368
    ? self
10369
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
10370
;
10371
10372
$.fn.popup = function(parameters) {
10373
  var
10374
    $allModules    = $(this),
10375
    $document      = $(document),
10376
    $window        = $(window),
10377
    $body          = $('body'),
10378
10379
    moduleSelector = $allModules.selector || '',
10380
10381
    hasTouch       = (true),
10382
    time           = new Date().getTime(),
10383
    performance    = [],
10384
10385
    query          = arguments[0],
10386
    methodInvoked  = (typeof query == 'string'),
10387
    queryArguments = [].slice.call(arguments, 1),
10388
10389
    returnedValue
10390
  ;
10391
  $allModules
10392
    .each(function() {
10393
      var
10394
        settings        = ( $.isPlainObject(parameters) )
10395
          ? $.extend(true, {}, $.fn.popup.settings, parameters)
10396
          : $.extend({}, $.fn.popup.settings),
10397
10398
        selector           = settings.selector,
10399
        className          = settings.className,
10400
        error              = settings.error,
10401
        metadata           = settings.metadata,
10402
        namespace          = settings.namespace,
10403
10404
        eventNamespace     = '.' + settings.namespace,
10405
        moduleNamespace    = 'module-' + namespace,
10406
10407
        $module            = $(this),
10408
        $context           = $(settings.context),
10409
        $scrollContext     = $(settings.scrollContext),
10410
        $boundary          = $(settings.boundary),
10411
        $target            = (settings.target)
10412
          ? $(settings.target)
10413
          : $module,
10414
10415
        $popup,
10416
        $offsetParent,
10417
10418
        searchDepth        = 0,
10419
        triedPositions     = false,
10420
        openedWithTouch    = false,
10421
10422
        element            = this,
10423
        instance           = $module.data(moduleNamespace),
10424
10425
        documentObserver,
10426
        elementNamespace,
10427
        id,
10428
        module
10429
      ;
10430
10431
      module = {
10432
10433
        // binds events
10434
        initialize: function() {
10435
          module.debug('Initializing', $module);
10436
          module.createID();
10437
          module.bind.events();
10438
          if(!module.exists() && settings.preserve) {
10439
            module.create();
10440
          }
10441
          if(settings.observeChanges) {
10442
            module.observeChanges();
10443
          }
10444
          module.instantiate();
10445
        },
10446
10447
        instantiate: function() {
10448
          module.verbose('Storing instance', module);
10449
          instance = module;
10450
          $module
10451
            .data(moduleNamespace, instance)
10452
          ;
10453
        },
10454
10455
        observeChanges: function() {
10456
          if('MutationObserver' in window) {
10457
            documentObserver = new MutationObserver(module.event.documentChanged);
0 ignored issues
show
Bug introduced by
The variable MutationObserver seems to be never declared. If this is a global, consider adding a /** global: MutationObserver */ 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...
10458
            documentObserver.observe(document, {
10459
              childList : true,
10460
              subtree   : true
10461
            });
10462
            module.debug('Setting up mutation observer', documentObserver);
10463
          }
10464
        },
10465
10466
        refresh: function() {
10467
          if(settings.popup) {
10468
            $popup = $(settings.popup).eq(0);
10469
          }
10470
          else {
10471
            if(settings.inline) {
10472
              $popup = $target.nextAll(selector.popup).eq(0);
10473
              settings.popup = $popup;
10474
            }
10475
          }
10476
          if(settings.popup) {
10477
            $popup.addClass(className.loading);
0 ignored issues
show
Bug introduced by
The variable $popup does not seem to be initialized in case settings.inline on line 10471 is false. Are you sure this can never be the case?
Loading history...
10478
            $offsetParent = module.get.offsetParent($target);
10479
            $popup.removeClass(className.loading);
10480
            if(settings.movePopup && module.has.popup() && module.get.offsetParent($popup)[0] !== $offsetParent[0]) {
10481
              module.debug('Moving popup to the same offset parent as target');
10482
              $popup
10483
                .detach()
10484
                .appendTo($offsetParent)
10485
              ;
10486
            }
10487
          }
10488
          else {
10489
            $offsetParent = (settings.inline)
10490
              ? module.get.offsetParent($target)
10491
              : module.has.popup()
10492
                ? module.get.offsetParent($target)
10493
                : $body
10494
            ;
10495
          }
10496
          if( $offsetParent.is('html') && $offsetParent[0] !== $body[0] ) {
10497
            module.debug('Setting page as offset parent');
10498
            $offsetParent = $body;
10499
          }
10500
          if( module.get.variation() ) {
10501
            module.set.variation();
10502
          }
10503
        },
10504
10505
        reposition: function() {
10506
          module.refresh();
10507
          module.set.position();
10508
        },
10509
10510
        destroy: function() {
10511
          module.debug('Destroying previous module');
10512
          if(documentObserver) {
10513
            documentObserver.disconnect();
10514
          }
10515
          // remove element only if was created dynamically
10516
          if($popup && !settings.preserve) {
10517
            module.removePopup();
10518
          }
10519
          // clear all timeouts
10520
          clearTimeout(module.hideTimer);
10521
          clearTimeout(module.showTimer);
10522
          // remove events
10523
          module.unbind.close();
10524
          module.unbind.events();
10525
          $module
10526
            .removeData(moduleNamespace)
10527
          ;
10528
        },
10529
10530
        event: {
10531
          start:  function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
10532
            var
10533
              delay = ($.isPlainObject(settings.delay))
10534
                ? settings.delay.show
10535
                : settings.delay
10536
            ;
10537
            clearTimeout(module.hideTimer);
10538
            if(!openedWithTouch) {
10539
              module.showTimer = setTimeout(module.show, delay);
10540
            }
10541
          },
10542
          end:  function() {
10543
            var
10544
              delay = ($.isPlainObject(settings.delay))
10545
                ? settings.delay.hide
10546
                : settings.delay
10547
            ;
10548
            clearTimeout(module.showTimer);
10549
            module.hideTimer = setTimeout(module.hide, delay);
10550
          },
10551
          touchstart: function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
10552
            openedWithTouch = true;
10553
            module.show();
10554
          },
10555
          resize: function() {
10556
            if( module.is.visible() ) {
10557
              module.set.position();
10558
            }
10559
          },
10560
          documentChanged: function(mutations) {
10561
            [].forEach.call(mutations, function(mutation) {
10562
              if(mutation.removedNodes) {
10563
                [].forEach.call(mutation.removedNodes, function(node) {
10564
                  if(node == element || $(node).find(element).length > 0) {
10565
                    module.debug('Element removed from DOM, tearing down events');
10566
                    module.destroy();
10567
                  }
10568
                });
10569
              }
10570
            });
10571
          },
10572
          hideGracefully: function(event) {
10573
            var
10574
              $target = $(event.target),
10575
              isInDOM = $.contains(document.documentElement, event.target),
10576
              inPopup = ($target.closest(selector.popup).length > 0)
10577
            ;
10578
            // don't close on clicks inside popup
10579
            if(event && !inPopup && isInDOM) {
10580
              module.debug('Click occurred outside popup hiding popup');
10581
              module.hide();
10582
            }
10583
            else {
10584
              module.debug('Click was inside popup, keeping popup open');
10585
            }
10586
          }
10587
        },
10588
10589
        // generates popup html from metadata
10590
        create: function() {
10591
          var
10592
            html      = module.get.html(),
10593
            title     = module.get.title(),
10594
            content   = module.get.content()
10595
          ;
10596
10597
          if(html || content || title) {
10598
            module.debug('Creating pop-up html');
10599
            if(!html) {
10600
              html = settings.templates.popup({
10601
                title   : title,
10602
                content : content
10603
              });
10604
            }
10605
            $popup = $('<div/>')
10606
              .addClass(className.popup)
10607
              .data(metadata.activator, $module)
10608
              .html(html)
10609
            ;
10610
            if(settings.inline) {
10611
              module.verbose('Inserting popup element inline', $popup);
10612
              $popup
10613
                .insertAfter($module)
10614
              ;
10615
            }
10616
            else {
10617
              module.verbose('Appending popup element to body', $popup);
10618
              $popup
10619
                .appendTo( $context )
10620
              ;
10621
            }
10622
            module.refresh();
10623
            module.set.variation();
10624
10625
            if(settings.hoverable) {
10626
              module.bind.popup();
10627
            }
10628
            settings.onCreate.call($popup, element);
10629
          }
10630
          else if($target.next(selector.popup).length !== 0) {
10631
            module.verbose('Pre-existing popup found');
10632
            settings.inline = true;
10633
            settings.popup  = $target.next(selector.popup).data(metadata.activator, $module);
10634
            module.refresh();
10635
            if(settings.hoverable) {
10636
              module.bind.popup();
10637
            }
10638
          }
10639
          else if(settings.popup) {
10640
            $(settings.popup).data(metadata.activator, $module);
10641
            module.verbose('Used popup specified in settings');
10642
            module.refresh();
10643
            if(settings.hoverable) {
10644
              module.bind.popup();
10645
            }
10646
          }
10647
          else {
10648
            module.debug('No content specified skipping display', element);
10649
          }
10650
        },
10651
10652
        createID: function() {
10653
          id = (Math.random().toString(16) + '000000000').substr(2, 8);
10654
          elementNamespace = '.' + id;
10655
          module.verbose('Creating unique id for element', id);
10656
        },
10657
10658
        // determines popup state
10659
        toggle: function() {
10660
          module.debug('Toggling pop-up');
10661
          if( module.is.hidden() ) {
10662
            module.debug('Popup is hidden, showing pop-up');
10663
            module.unbind.close();
10664
            module.show();
10665
          }
10666
          else {
10667
            module.debug('Popup is visible, hiding pop-up');
10668
            module.hide();
10669
          }
10670
        },
10671
10672
        show: function(callback) {
10673
          callback = callback || function(){};
10674
          module.debug('Showing pop-up', settings.transition);
10675
          if(module.is.hidden() && !( module.is.active() && module.is.dropdown()) ) {
10676
            if( !module.exists() ) {
10677
              module.create();
10678
            }
10679
            if(settings.onShow.call($popup, element) === false) {
10680
              module.debug('onShow callback returned false, cancelling popup animation');
10681
              return;
10682
            }
10683
            else if(!settings.preserve && !settings.popup) {
10684
              module.refresh();
10685
            }
10686
            if( $popup && module.set.position() ) {
10687
              module.save.conditions();
10688
              if(settings.exclusive) {
10689
                module.hideAll();
10690
              }
10691
              module.animate.show(callback);
10692
            }
10693
          }
10694
        },
10695
10696
10697
        hide: function(callback) {
10698
          callback = callback || function(){};
10699
          if( module.is.visible() || module.is.animating() ) {
10700
            if(settings.onHide.call($popup, element) === false) {
10701
              module.debug('onHide callback returned false, cancelling popup animation');
10702
              return;
10703
            }
10704
            module.remove.visible();
10705
            module.unbind.close();
10706
            module.restore.conditions();
10707
            module.animate.hide(callback);
10708
          }
10709
        },
10710
10711
        hideAll: function() {
10712
          $(selector.popup)
10713
            .filter('.' + className.popupVisible)
10714
            .each(function() {
10715
              $(this)
10716
                .data(metadata.activator)
10717
                  .popup('hide')
10718
              ;
10719
            })
10720
          ;
10721
        },
10722
        exists: function() {
10723
          if(!$popup) {
10724
            return false;
10725
          }
10726
          if(settings.inline || settings.popup) {
10727
            return ( module.has.popup() );
10728
          }
10729
          else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
10730
            return ( $popup.closest($context).length >= 1 )
10731
              ? true
10732
              : false
10733
            ;
10734
          }
10735
        },
10736
10737
        removePopup: function() {
10738
          if( module.has.popup() && !settings.popup) {
10739
            module.debug('Removing popup', $popup);
10740
            $popup.remove();
10741
            $popup = undefined;
10742
            settings.onRemove.call($popup, element);
10743
          }
10744
        },
10745
10746
        save: {
10747
          conditions: function() {
10748
            module.cache = {
10749
              title: $module.attr('title')
10750
            };
10751
            if (module.cache.title) {
10752
              $module.removeAttr('title');
10753
            }
10754
            module.verbose('Saving original attributes', module.cache.title);
10755
          }
10756
        },
10757
        restore: {
10758
          conditions: function() {
10759
            if(module.cache && module.cache.title) {
10760
              $module.attr('title', module.cache.title);
10761
              module.verbose('Restoring original attributes', module.cache.title);
10762
            }
10763
            return true;
10764
          }
10765
        },
10766
        supports: {
10767
          svg: function() {
10768
            return (typeof SVGGraphicsElement === 'undefined');
0 ignored issues
show
Bug introduced by
The variable SVGGraphicsElement seems to be never declared. If this is a global, consider adding a /** global: SVGGraphicsElement */ 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...
10769
          }
10770
        },
10771
        animate: {
10772
          show: function(callback) {
10773
            callback = $.isFunction(callback) ? callback : function(){};
10774
            if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
10775
              module.set.visible();
10776
              $popup
10777
                .transition({
10778
                  animation  : settings.transition + ' in',
10779
                  queue      : false,
10780
                  debug      : settings.debug,
10781
                  verbose    : settings.verbose,
10782
                  duration   : settings.duration,
10783
                  onComplete : function() {
10784
                    module.bind.close();
10785
                    callback.call($popup, element);
10786
                    settings.onVisible.call($popup, element);
10787
                  }
10788
                })
10789
              ;
10790
            }
10791
            else {
10792
              module.error(error.noTransition);
10793
            }
10794
          },
10795
          hide: function(callback) {
10796
            callback = $.isFunction(callback) ? callback : function(){};
10797
            module.debug('Hiding pop-up');
10798
            if(settings.onHide.call($popup, element) === false) {
10799
              module.debug('onHide callback returned false, cancelling popup animation');
10800
              return;
10801
            }
10802
            if(settings.transition && $.fn.transition !== undefined && $module.transition('is supported')) {
10803
              $popup
10804
                .transition({
10805
                  animation  : settings.transition + ' out',
10806
                  queue      : false,
10807
                  duration   : settings.duration,
10808
                  debug      : settings.debug,
10809
                  verbose    : settings.verbose,
10810
                  onComplete : function() {
10811
                    module.reset();
10812
                    callback.call($popup, element);
10813
                    settings.onHidden.call($popup, element);
10814
                  }
10815
                })
10816
              ;
10817
            }
10818
            else {
10819
              module.error(error.noTransition);
10820
            }
10821
          }
10822
        },
10823
10824
        change: {
10825
          content: function(html) {
10826
            $popup.html(html);
10827
          }
10828
        },
10829
10830
        get: {
10831
          html: function() {
10832
            $module.removeData(metadata.html);
10833
            return $module.data(metadata.html) || settings.html;
10834
          },
10835
          title: function() {
10836
            $module.removeData(metadata.title);
10837
            return $module.data(metadata.title) || settings.title;
10838
          },
10839
          content: function() {
10840
            $module.removeData(metadata.content);
10841
            return $module.data(metadata.content) || $module.attr('title') || settings.content;
10842
          },
10843
          variation: function() {
10844
            $module.removeData(metadata.variation);
10845
            return $module.data(metadata.variation) || settings.variation;
10846
          },
10847
          popup: function() {
10848
            return $popup;
10849
          },
10850
          popupOffset: function() {
10851
            return $popup.offset();
10852
          },
10853
          calculations: function() {
10854
            var
10855
              targetElement    = $target[0],
10856
              isWindow         = ($boundary[0] == window),
10857
              targetPosition   = (settings.inline || (settings.popup && settings.movePopup))
10858
                ? $target.position()
10859
                : $target.offset(),
10860
              screenPosition = (isWindow)
10861
                ? { top: 0, left: 0 }
10862
                : $boundary.offset(),
10863
              calculations   = {},
0 ignored issues
show
Unused Code introduced by
The assignment to variable calculations seems to be never used. Consider removing it.
Loading history...
10864
              scroll = (isWindow)
10865
                ? { top: $window.scrollTop(), left: $window.scrollLeft() }
10866
                : { top: 0, left: 0},
10867
              screen
10868
            ;
10869
            calculations = {
10870
              // element which is launching popup
10871
              target : {
10872
                element : $target[0],
10873
                width   : $target.outerWidth(),
10874
                height  : $target.outerHeight(),
10875
                top     : targetPosition.top,
10876
                left    : targetPosition.left,
10877
                margin  : {}
10878
              },
10879
              // popup itself
10880
              popup : {
10881
                width  : $popup.outerWidth(),
10882
                height : $popup.outerHeight()
10883
              },
10884
              // offset container (or 3d context)
10885
              parent : {
10886
                width  : $offsetParent.outerWidth(),
10887
                height : $offsetParent.outerHeight()
10888
              },
10889
              // screen boundaries
10890
              screen : {
10891
                top  : screenPosition.top,
10892
                left : screenPosition.left,
10893
                scroll: {
10894
                  top  : scroll.top,
10895
                  left : scroll.left
10896
                },
10897
                width  : $boundary.width(),
10898
                height : $boundary.height()
10899
              }
10900
            };
10901
10902
            // add in container calcs if fluid
10903
            if( settings.setFluidWidth && module.is.fluid() ) {
10904
              calculations.container = {
10905
                width: $popup.parent().outerWidth()
10906
              };
10907
              calculations.popup.width = calculations.container.width;
10908
            }
10909
10910
            // add in margins if inline
10911
            calculations.target.margin.top = (settings.inline)
10912
              ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-top'), 10)
10913
              : 0
10914
            ;
10915
            calculations.target.margin.left = (settings.inline)
10916
              ? module.is.rtl()
10917
                ? parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-right'), 10)
10918
                : parseInt( window.getComputedStyle(targetElement).getPropertyValue('margin-left'), 10)
10919
              : 0
10920
            ;
10921
            // calculate screen boundaries
10922
            screen = calculations.screen;
10923
            calculations.boundary = {
10924
              top    : screen.top + screen.scroll.top,
10925
              bottom : screen.top + screen.scroll.top + screen.height,
10926
              left   : screen.left + screen.scroll.left,
10927
              right  : screen.left + screen.scroll.left + screen.width
10928
            };
10929
            return calculations;
10930
          },
10931
          id: function() {
10932
            return id;
10933
          },
10934
          startEvent: function() {
10935
            if(settings.on == 'hover') {
10936
              return 'mouseenter';
10937
            }
10938
            else if(settings.on == 'focus') {
10939
              return 'focus';
10940
            }
10941
            return false;
10942
          },
10943
          scrollEvent: function() {
10944
            return 'scroll';
10945
          },
10946
          endEvent: function() {
10947
            if(settings.on == 'hover') {
10948
              return 'mouseleave';
10949
            }
10950
            else if(settings.on == 'focus') {
10951
              return 'blur';
10952
            }
10953
            return false;
10954
          },
10955
          distanceFromBoundary: function(offset, calculations) {
10956
            var
10957
              distanceFromBoundary = {},
10958
              popup,
10959
              boundary
10960
            ;
10961
            calculations = calculations || module.get.calculations();
10962
10963
            // shorthand
10964
            popup        = calculations.popup;
10965
            boundary     = calculations.boundary;
10966
10967
            if(offset) {
10968
              distanceFromBoundary = {
10969
                top    : (offset.top - boundary.top),
10970
                left   : (offset.left - boundary.left),
10971
                right  : (boundary.right - (offset.left + popup.width) ),
10972
                bottom : (boundary.bottom - (offset.top + popup.height) )
10973
              };
10974
              module.verbose('Distance from boundaries determined', offset, distanceFromBoundary);
10975
            }
10976
            return distanceFromBoundary;
10977
          },
10978
          offsetParent: function($target) {
10979
            var
10980
              element = ($target !== undefined)
10981
                ? $target[0]
10982
                : $module[0],
10983
              parentNode = element.parentNode,
10984
              $node    = $(parentNode)
10985
            ;
10986
            if(parentNode) {
10987
              var
10988
                is2D     = ($node.css('transform') === 'none'),
10989
                isStatic = ($node.css('position') === 'static'),
10990
                isHTML   = $node.is('html')
10991
              ;
10992
              while(parentNode && !isHTML && isStatic && is2D) {
10993
                parentNode = parentNode.parentNode;
10994
                $node    = $(parentNode);
10995
                is2D     = ($node.css('transform') === 'none');
10996
                isStatic = ($node.css('position') === 'static');
10997
                isHTML   = $node.is('html');
10998
              }
10999
            }
11000
            return ($node && $node.length > 0)
11001
              ? $node
11002
              : $()
11003
            ;
11004
          },
11005
          positions: function() {
11006
            return {
11007
              'top left'      : false,
11008
              'top center'    : false,
11009
              'top right'     : false,
11010
              'bottom left'   : false,
11011
              'bottom center' : false,
11012
              'bottom right'  : false,
11013
              'left center'   : false,
11014
              'right center'  : false
11015
            };
11016
          },
11017
          nextPosition: function(position) {
11018
            var
11019
              positions          = position.split(' '),
11020
              verticalPosition   = positions[0],
11021
              horizontalPosition = positions[1],
11022
              opposite = {
11023
                top    : 'bottom',
11024
                bottom : 'top',
11025
                left   : 'right',
11026
                right  : 'left'
11027
              },
11028
              adjacent = {
11029
                left   : 'center',
11030
                center : 'right',
11031
                right  : 'left'
11032
              },
11033
              backup = {
11034
                'top left'      : 'top center',
11035
                'top center'    : 'top right',
11036
                'top right'     : 'right center',
11037
                'right center'  : 'bottom right',
11038
                'bottom right'  : 'bottom center',
11039
                'bottom center' : 'bottom left',
11040
                'bottom left'   : 'left center',
11041
                'left center'   : 'top left'
11042
              },
11043
              adjacentsAvailable = (verticalPosition == 'top' || verticalPosition == 'bottom'),
11044
              oppositeTried = false,
11045
              adjacentTried = false,
11046
              nextPosition  = false
11047
            ;
11048
            if(!triedPositions) {
11049
              module.verbose('All available positions available');
11050
              triedPositions = module.get.positions();
11051
            }
11052
11053
            module.debug('Recording last position tried', position);
11054
            triedPositions[position] = true;
11055
11056
            if(settings.prefer === 'opposite') {
11057
              nextPosition  = [opposite[verticalPosition], horizontalPosition];
11058
              nextPosition  = nextPosition.join(' ');
11059
              oppositeTried = (triedPositions[nextPosition] === true);
11060
              module.debug('Trying opposite strategy', nextPosition);
11061
            }
11062
            if((settings.prefer === 'adjacent') && adjacentsAvailable ) {
11063
              nextPosition  = [verticalPosition, adjacent[horizontalPosition]];
11064
              nextPosition  = nextPosition.join(' ');
11065
              adjacentTried = (triedPositions[nextPosition] === true);
11066
              module.debug('Trying adjacent strategy', nextPosition);
11067
            }
11068
            if(adjacentTried || oppositeTried) {
11069
              module.debug('Using backup position', nextPosition);
11070
              nextPosition = backup[position];
11071
            }
11072
            return nextPosition;
11073
          }
11074
        },
11075
11076
        set: {
11077
          position: function(position, calculations) {
11078
11079
            // exit conditions
11080
            if($target.length === 0 || $popup.length === 0) {
11081
              module.error(error.notFound);
11082
              return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
11083
            }
11084
            var
11085
              offset,
11086
              distanceAway,
11087
              target,
11088
              popup,
11089
              parent,
11090
              positioning,
11091
              popupOffset,
11092
              distanceFromBoundary
11093
            ;
11094
11095
            calculations = calculations || module.get.calculations();
11096
            position     = position     || $module.data(metadata.position) || settings.position;
11097
11098
            offset       = $module.data(metadata.offset) || settings.offset;
11099
            distanceAway = settings.distanceAway;
11100
11101
            // shorthand
11102
            target = calculations.target;
11103
            popup  = calculations.popup;
11104
            parent = calculations.parent;
11105
11106
            if(target.width === 0 && target.height === 0 && !module.is.svg(target.element)) {
11107
              module.debug('Popup target is hidden, no action taken');
11108
              return false;
11109
            }
11110
11111
            if(settings.inline) {
11112
              module.debug('Adding margin to calculation', target.margin);
11113
              if(position == 'left center' || position == 'right center') {
11114
                offset       +=  target.margin.top;
11115
                distanceAway += -target.margin.left;
11116
              }
11117
              else if (position == 'top left' || position == 'top center' || position == 'top right') {
11118
                offset       += target.margin.left;
11119
                distanceAway -= target.margin.top;
11120
              }
11121
              else {
11122
                offset       += target.margin.left;
11123
                distanceAway += target.margin.top;
11124
              }
11125
            }
11126
11127
            module.debug('Determining popup position from calculations', position, calculations);
11128
11129
            if (module.is.rtl()) {
11130
              position = position.replace(/left|right/g, function (match) {
11131
                return (match == 'left')
11132
                  ? 'right'
11133
                  : 'left'
11134
                ;
11135
              });
11136
              module.debug('RTL: Popup position updated', position);
11137
            }
11138
11139
            // if last attempt use specified last resort position
11140
            if(searchDepth == settings.maxSearchDepth && typeof settings.lastResort === 'string') {
11141
              position = settings.lastResort;
11142
            }
11143
11144
            switch (position) {
11145
              case 'top left':
11146
                positioning = {
11147
                  top    : 'auto',
11148
                  bottom : parent.height - target.top + distanceAway,
11149
                  left   : target.left + offset,
11150
                  right  : 'auto'
11151
                };
11152
              break;
11153
              case 'top center':
11154
                positioning = {
11155
                  bottom : parent.height - target.top + distanceAway,
11156
                  left   : target.left + (target.width / 2) - (popup.width / 2) + offset,
11157
                  top    : 'auto',
11158
                  right  : 'auto'
11159
                };
11160
              break;
11161
              case 'top right':
11162
                positioning = {
11163
                  bottom :  parent.height - target.top + distanceAway,
11164
                  right  :  parent.width - target.left - target.width - offset,
11165
                  top    : 'auto',
11166
                  left   : 'auto'
11167
                };
11168
              break;
11169
              case 'left center':
11170
                positioning = {
11171
                  top    : target.top + (target.height / 2) - (popup.height / 2) + offset,
11172
                  right  : parent.width - target.left + distanceAway,
11173
                  left   : 'auto',
11174
                  bottom : 'auto'
11175
                };
11176
              break;
11177
              case 'right center':
11178
                positioning = {
11179
                  top    : target.top + (target.height / 2) - (popup.height / 2) + offset,
11180
                  left   : target.left + target.width + distanceAway,
11181
                  bottom : 'auto',
11182
                  right  : 'auto'
11183
                };
11184
              break;
11185
              case 'bottom left':
11186
                positioning = {
11187
                  top    : target.top + target.height + distanceAway,
11188
                  left   : target.left + offset,
11189
                  bottom : 'auto',
11190
                  right  : 'auto'
11191
                };
11192
              break;
11193
              case 'bottom center':
11194
                positioning = {
11195
                  top    : target.top + target.height + distanceAway,
11196
                  left   : target.left + (target.width / 2) - (popup.width / 2) + offset,
11197
                  bottom : 'auto',
11198
                  right  : 'auto'
11199
                };
11200
              break;
11201
              case 'bottom right':
11202
                positioning = {
11203
                  top    : target.top + target.height + distanceAway,
11204
                  right  : parent.width - target.left  - target.width - offset,
11205
                  left   : 'auto',
11206
                  bottom : 'auto'
11207
                };
11208
              break;
11209
            }
11210
            if(positioning === undefined) {
0 ignored issues
show
Bug introduced by
The variable positioning seems to not be initialized for all possible execution paths.
Loading history...
11211
              module.error(error.invalidPosition, position);
11212
            }
11213
11214
            module.debug('Calculated popup positioning values', positioning);
11215
11216
            // tentatively place on stage
11217
            $popup
11218
              .css(positioning)
11219
              .removeClass(className.position)
11220
              .addClass(position)
11221
              .addClass(className.loading)
11222
            ;
11223
11224
            popupOffset = module.get.popupOffset();
11225
11226
            // see if any boundaries are surpassed with this tentative position
11227
            distanceFromBoundary = module.get.distanceFromBoundary(popupOffset, calculations);
11228
11229
            if( module.is.offstage(distanceFromBoundary, position) ) {
11230
              module.debug('Position is outside viewport', position);
11231
              if(searchDepth < settings.maxSearchDepth) {
11232
                searchDepth++;
11233
                position = module.get.nextPosition(position);
11234
                module.debug('Trying new position', position);
11235
                return ($popup)
11236
                  ? module.set.position(position, calculations)
11237
                  : false
11238
                ;
11239
              }
11240
              else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
11241
                if(settings.lastResort) {
11242
                  module.debug('No position found, showing with last position');
11243
                }
11244
                else {
11245
                  module.debug('Popup could not find a position to display', $popup);
11246
                  module.error(error.cannotPlace, element);
11247
                  module.remove.attempts();
11248
                  module.remove.loading();
11249
                  module.reset();
11250
                  settings.onUnplaceable.call($popup, element);
11251
                  return false;
11252
                }
11253
              }
11254
            }
11255
            module.debug('Position is on stage', position);
11256
            module.remove.attempts();
11257
            module.remove.loading();
11258
            if( settings.setFluidWidth && module.is.fluid() ) {
11259
              module.set.fluidWidth(calculations);
11260
            }
11261
            return true;
11262
          },
11263
11264
          fluidWidth: function(calculations) {
11265
            calculations = calculations || module.get.calculations();
11266
            module.debug('Automatically setting element width to parent width', calculations.parent.width);
11267
            $popup.css('width', calculations.container.width);
11268
          },
11269
11270
          variation: function(variation) {
11271
            variation = variation || module.get.variation();
11272
            if(variation && module.has.popup() ) {
11273
              module.verbose('Adding variation to popup', variation);
11274
              $popup.addClass(variation);
11275
            }
11276
          },
11277
11278
          visible: function() {
11279
            $module.addClass(className.visible);
11280
          }
11281
        },
11282
11283
        remove: {
11284
          loading: function() {
11285
            $popup.removeClass(className.loading);
11286
          },
11287
          variation: function(variation) {
11288
            variation = variation || module.get.variation();
11289
            if(variation) {
11290
              module.verbose('Removing variation', variation);
11291
              $popup.removeClass(variation);
11292
            }
11293
          },
11294
          visible: function() {
11295
            $module.removeClass(className.visible);
11296
          },
11297
          attempts: function() {
11298
            module.verbose('Resetting all searched positions');
11299
            searchDepth    = 0;
11300
            triedPositions = false;
11301
          }
11302
        },
11303
11304
        bind: {
11305
          events: function() {
11306
            module.debug('Binding popup events to module');
11307
            if(settings.on == 'click') {
11308
              $module
11309
                .on('click' + eventNamespace, module.toggle)
11310
              ;
11311
            }
11312
            if(settings.on == 'hover' && hasTouch) {
11313
              $module
11314
                .on('touchstart' + eventNamespace, module.event.touchstart)
11315
              ;
11316
            }
11317
            if( module.get.startEvent() ) {
11318
              $module
11319
                .on(module.get.startEvent() + eventNamespace, module.event.start)
11320
                .on(module.get.endEvent() + eventNamespace, module.event.end)
11321
              ;
11322
            }
11323
            if(settings.target) {
11324
              module.debug('Target set to element', $target);
11325
            }
11326
            $window.on('resize' + elementNamespace, module.event.resize);
11327
          },
11328
          popup: function() {
11329
            module.verbose('Allowing hover events on popup to prevent closing');
11330
            if( $popup && module.has.popup() ) {
11331
              $popup
11332
                .on('mouseenter' + eventNamespace, module.event.start)
11333
                .on('mouseleave' + eventNamespace, module.event.end)
11334
              ;
11335
            }
11336
          },
11337
          close: function() {
11338
            if(settings.hideOnScroll === true || (settings.hideOnScroll == 'auto' && settings.on != 'click')) {
11339
              module.bind.closeOnScroll();
11340
            }
11341
            if(settings.on == 'hover' && openedWithTouch) {
11342
              module.bind.touchClose();
11343
            }
11344
            if(settings.on == 'click' && settings.closable) {
11345
              module.bind.clickaway();
11346
            }
11347
          },
11348
          closeOnScroll: function() {
11349
            module.verbose('Binding scroll close event to document');
11350
            $scrollContext
11351
              .one(module.get.scrollEvent() + elementNamespace, module.event.hideGracefully)
11352
            ;
11353
          },
11354
          touchClose: function() {
11355
            module.verbose('Binding popup touchclose event to document');
11356
            $document
11357
              .on('touchstart' + elementNamespace, function(event) {
11358
                module.verbose('Touched away from popup');
11359
                module.event.hideGracefully.call(element, event);
11360
              })
11361
            ;
11362
          },
11363
          clickaway: function() {
11364
            module.verbose('Binding popup close event to document');
11365
            $document
11366
              .on('click' + elementNamespace, function(event) {
11367
                module.verbose('Clicked away from popup');
11368
                module.event.hideGracefully.call(element, event);
11369
              })
11370
            ;
11371
          }
11372
        },
11373
11374
        unbind: {
11375
          events: function() {
11376
            $window
11377
              .off(elementNamespace)
11378
            ;
11379
            $module
11380
              .off(eventNamespace)
11381
            ;
11382
          },
11383
          close: function() {
11384
            $document
11385
              .off(elementNamespace)
11386
            ;
11387
            $scrollContext
11388
              .off(elementNamespace)
11389
            ;
11390
          },
11391
        },
11392
11393
        has: {
11394
          popup: function() {
11395
            return ($popup && $popup.length > 0);
11396
          }
11397
        },
11398
11399
        is: {
11400
          offstage: function(distanceFromBoundary, position) {
11401
            var
11402
              offstage = []
11403
            ;
11404
            // return boundaries that have been surpassed
11405
            $.each(distanceFromBoundary, function(direction, distance) {
11406
              if(distance < -settings.jitter) {
11407
                module.debug('Position exceeds allowable distance from edge', direction, distance, position);
11408
                offstage.push(direction);
11409
              }
11410
            });
11411
            if(offstage.length > 0) {
11412
              return true;
11413
            }
11414
            else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
11415
              return false;
11416
            }
11417
          },
11418
          svg: function(element) {
11419
            return module.supports.svg() && (element instanceof SVGGraphicsElement);
0 ignored issues
show
Bug introduced by
The variable SVGGraphicsElement seems to be never declared. If this is a global, consider adding a /** global: SVGGraphicsElement */ 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...
11420
          },
11421
          active: function() {
11422
            return $module.hasClass(className.active);
11423
          },
11424
          animating: function() {
11425
            return ($popup !== undefined && $popup.hasClass(className.animating) );
11426
          },
11427
          fluid: function() {
11428
            return ($popup !== undefined && $popup.hasClass(className.fluid));
11429
          },
11430
          visible: function() {
11431
            return ($popup !== undefined && $popup.hasClass(className.popupVisible));
11432
          },
11433
          dropdown: function() {
11434
            return $module.hasClass(className.dropdown);
11435
          },
11436
          hidden: function() {
11437
            return !module.is.visible();
11438
          },
11439
          rtl: function () {
11440
            return $module.css('direction') == 'rtl';
11441
          }
11442
        },
11443
11444
        reset: function() {
11445
          module.remove.visible();
11446
          if(settings.preserve) {
11447
            if($.fn.transition !== undefined) {
11448
              $popup
11449
                .transition('remove transition')
11450
              ;
11451
            }
11452
          }
11453
          else {
11454
            module.removePopup();
11455
          }
11456
        },
11457
11458
        setting: function(name, value) {
11459
          if( $.isPlainObject(name) ) {
11460
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
11461
          }
11462
          else if(value !== undefined) {
11463
            settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
11464
          }
11465
          else {
11466
            return settings[name];
11467
          }
11468
        },
11469
        internal: function(name, value) {
11470
          if( $.isPlainObject(name) ) {
11471
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
11472
          }
11473
          else if(value !== undefined) {
11474
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
11475
          }
11476
          else {
11477
            return module[name];
11478
          }
11479
        },
11480
        debug: function() {
11481
          if(!settings.silent && settings.debug) {
11482
            if(settings.performance) {
11483
              module.performance.log(arguments);
11484
            }
11485
            else {
11486
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
11487
              module.debug.apply(console, arguments);
11488
            }
11489
          }
11490
        },
11491
        verbose: function() {
11492
          if(!settings.silent && settings.verbose && settings.debug) {
11493
            if(settings.performance) {
11494
              module.performance.log(arguments);
11495
            }
11496
            else {
11497
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
11498
              module.verbose.apply(console, arguments);
11499
            }
11500
          }
11501
        },
11502
        error: function() {
11503
          if(!settings.silent) {
11504
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
11505
            module.error.apply(console, arguments);
11506
          }
11507
        },
11508
        performance: {
11509
          log: function(message) {
11510
            var
11511
              currentTime,
11512
              executionTime,
11513
              previousTime
11514
            ;
11515
            if(settings.performance) {
11516
              currentTime   = new Date().getTime();
11517
              previousTime  = time || currentTime;
11518
              executionTime = currentTime - previousTime;
11519
              time          = currentTime;
11520
              performance.push({
11521
                'Name'           : message[0],
11522
                'Arguments'      : [].slice.call(message, 1) || '',
11523
                'Element'        : element,
11524
                'Execution Time' : executionTime
11525
              });
11526
            }
11527
            clearTimeout(module.performance.timer);
11528
            module.performance.timer = setTimeout(module.performance.display, 500);
11529
          },
11530
          display: function() {
11531
            var
11532
              title = settings.name + ':',
11533
              totalTime = 0
11534
            ;
11535
            time = false;
11536
            clearTimeout(module.performance.timer);
11537
            $.each(performance, function(index, data) {
11538
              totalTime += data['Execution Time'];
11539
            });
11540
            title += ' ' + totalTime + 'ms';
11541
            if(moduleSelector) {
11542
              title += ' \'' + moduleSelector + '\'';
11543
            }
11544
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
11545
              console.groupCollapsed(title);
11546
              if(console.table) {
11547
                console.table(performance);
11548
              }
11549
              else {
11550
                $.each(performance, function(index, data) {
11551
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
11552
                });
11553
              }
11554
              console.groupEnd();
11555
            }
11556
            performance = [];
11557
          }
11558
        },
11559
        invoke: function(query, passedArguments, context) {
11560
          var
11561
            object = instance,
11562
            maxDepth,
11563
            found,
11564
            response
11565
          ;
11566
          passedArguments = passedArguments || queryArguments;
11567
          context         = element         || context;
11568
          if(typeof query == 'string' && object !== undefined) {
11569
            query    = query.split(/[\. ]/);
11570
            maxDepth = query.length - 1;
11571
            $.each(query, function(depth, value) {
11572
              var camelCaseValue = (depth != maxDepth)
11573
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
11574
                : query
11575
              ;
11576
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
11577
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
11578
              }
11579
              else if( object[camelCaseValue] !== undefined ) {
11580
                found = object[camelCaseValue];
11581
                return false;
11582
              }
11583
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
11584
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
11585
              }
11586
              else if( object[value] !== undefined ) {
11587
                found = object[value];
11588
                return false;
11589
              }
11590
              else {
11591
                return false;
11592
              }
11593
            });
11594
          }
11595
          if ( $.isFunction( found ) ) {
11596
            response = found.apply(context, passedArguments);
11597
          }
11598
          else if(found !== undefined) {
11599
            response = found;
11600
          }
11601
          if($.isArray(returnedValue)) {
11602
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 11598 is false. Are you sure the function push handles undefined variables?
Loading history...
11603
          }
11604
          else if(returnedValue !== undefined) {
11605
            returnedValue = [returnedValue, response];
11606
          }
11607
          else if(response !== undefined) {
11608
            returnedValue = response;
11609
          }
11610
          return found;
11611
        }
11612
      };
11613
11614
      if(methodInvoked) {
11615
        if(instance === undefined) {
11616
          module.initialize();
11617
        }
11618
        module.invoke(query);
11619
      }
11620
      else {
11621
        if(instance !== undefined) {
11622
          instance.invoke('destroy');
11623
        }
11624
        module.initialize();
11625
      }
11626
    })
11627
  ;
11628
11629
  return (returnedValue !== undefined)
11630
    ? returnedValue
11631
    : this
11632
  ;
11633
};
11634
11635
$.fn.popup.settings = {
11636
11637
  name           : 'Popup',
11638
11639
  // module settings
11640
  silent         : false,
11641
  debug          : false,
11642
  verbose        : false,
11643
  performance    : true,
11644
  namespace      : 'popup',
11645
11646
  // whether it should use dom mutation observers
11647
  observeChanges : true,
11648
11649
  // callback only when element added to dom
11650
  onCreate       : function(){},
11651
11652
  // callback before element removed from dom
11653
  onRemove       : function(){},
11654
11655
  // callback before show animation
11656
  onShow         : function(){},
11657
11658
  // callback after show animation
11659
  onVisible      : function(){},
11660
11661
  // callback before hide animation
11662
  onHide         : function(){},
11663
11664
  // callback when popup cannot be positioned in visible screen
11665
  onUnplaceable  : function(){},
11666
11667
  // callback after hide animation
11668
  onHidden       : function(){},
11669
11670
  // when to show popup
11671
  on             : 'hover',
11672
11673
  // element to use to determine if popup is out of boundary
11674
  boundary       : window,
11675
11676
  // whether to add touchstart events when using hover
11677
  addTouchEvents : true,
11678
11679
  // default position relative to element
11680
  position       : 'top left',
11681
11682
  // name of variation to use
11683
  variation      : '',
11684
11685
  // whether popup should be moved to context
11686
  movePopup      : true,
11687
11688
  // element which popup should be relative to
11689
  target         : false,
11690
11691
  // jq selector or element that should be used as popup
11692
  popup          : false,
11693
11694
  // popup should remain inline next to activator
11695
  inline         : false,
11696
11697
  // popup should be removed from page on hide
11698
  preserve       : false,
11699
11700
  // popup should not close when being hovered on
11701
  hoverable      : false,
11702
11703
  // explicitly set content
11704
  content        : false,
11705
11706
  // explicitly set html
11707
  html           : false,
11708
11709
  // explicitly set title
11710
  title          : false,
11711
11712
  // whether automatically close on clickaway when on click
11713
  closable       : true,
11714
11715
  // automatically hide on scroll
11716
  hideOnScroll   : 'auto',
11717
11718
  // hide other popups on show
11719
  exclusive      : false,
11720
11721
  // context to attach popups
11722
  context        : 'body',
11723
11724
  // context for binding scroll events
11725
  scrollContext  : window,
11726
11727
  // position to prefer when calculating new position
11728
  prefer         : 'opposite',
11729
11730
  // specify position to appear even if it doesn't fit
11731
  lastResort     : false,
11732
11733
  // delay used to prevent accidental refiring of animations due to user error
11734
  delay        : {
11735
    show : 50,
11736
    hide : 70
11737
  },
11738
11739
  // whether fluid variation should assign width explicitly
11740
  setFluidWidth  : true,
11741
11742
  // transition settings
11743
  duration       : 200,
11744
  transition     : 'scale',
11745
11746
  // distance away from activating element in px
11747
  distanceAway   : 0,
11748
11749
  // number of pixels an element is allowed to be "offstage" for a position to be chosen (allows for rounding)
11750
  jitter         : 2,
11751
11752
  // offset on aligning axis from calculated position
11753
  offset         : 0,
11754
11755
  // maximum times to look for a position before failing (9 positions total)
11756
  maxSearchDepth : 15,
11757
11758
  error: {
11759
    invalidPosition : 'The position you specified is not a valid position',
11760
    cannotPlace     : 'Popup does not fit within the boundaries of the viewport',
11761
    method          : 'The method you called is not defined.',
11762
    noTransition    : 'This module requires ui transitions <https://github.com/Semantic-Org/UI-Transition>',
11763
    notFound        : 'The target or popup you specified does not exist on the page'
11764
  },
11765
11766
  metadata: {
11767
    activator : 'activator',
11768
    content   : 'content',
11769
    html      : 'html',
11770
    offset    : 'offset',
11771
    position  : 'position',
11772
    title     : 'title',
11773
    variation : 'variation'
11774
  },
11775
11776
  className   : {
11777
    active       : 'active',
11778
    animating    : 'animating',
11779
    dropdown     : 'dropdown',
11780
    fluid        : 'fluid',
11781
    loading      : 'loading',
11782
    popup        : 'ui popup',
11783
    position     : 'top left center bottom right',
11784
    visible      : 'visible',
11785
    popupVisible : 'visible'
11786
  },
11787
11788
  selector    : {
11789
    popup    : '.ui.popup'
11790
  },
11791
11792
  templates: {
11793
    escape: function(string) {
11794
      var
11795
        badChars     = /[&<>"'`]/g,
11796
        shouldEscape = /[&<>"'`]/,
11797
        escape       = {
11798
          "&": "&amp;",
11799
          "<": "&lt;",
11800
          ">": "&gt;",
11801
          '"': "&quot;",
11802
          "'": "&#x27;",
11803
          "`": "&#x60;"
11804
        },
11805
        escapedChar  = function(chr) {
11806
          return escape[chr];
11807
        }
11808
      ;
11809
      if(shouldEscape.test(string)) {
11810
        return string.replace(badChars, escapedChar);
11811
      }
11812
      return string;
11813
    },
11814
    popup: function(text) {
11815
      var
11816
        html   = '',
11817
        escape = $.fn.popup.settings.templates.escape
11818
      ;
11819
      if(typeof text !== undefined) {
11820
        if(typeof text.title !== undefined && text.title) {
11821
          text.title = escape(text.title);
11822
          html += '<div class="header">' + text.title + '</div>';
11823
        }
11824
        if(typeof text.content !== undefined && text.content) {
11825
          text.content = escape(text.content);
11826
          html += '<div class="content">' + text.content + '</div>';
11827
        }
11828
      }
11829
      return html;
11830
    }
11831
  }
11832
11833
};
11834
11835
11836
})( jQuery, window, document );
11837
11838
/*!
11839
 * # Semantic UI 2.2.11 - Progress
11840
 * http://github.com/semantic-org/semantic-ui/
11841
 *
11842
 *
11843
 * Released under the MIT license
11844
 * http://opensource.org/licenses/MIT
11845
 *
11846
 */
11847
11848 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
11849
11850
"use strict";
11851
11852
window = (typeof window != 'undefined' && window.Math == Math)
11853
  ? window
11854
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
11855
    ? self
11856
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
11857
;
11858
11859
var
11860
  global = (typeof window != 'undefined' && window.Math == Math)
0 ignored issues
show
Unused Code introduced by
The variable global seems to be never used. Consider removing it.
Loading history...
11861
    ? window
11862
    : (typeof self != 'undefined' && self.Math == Math)
11863
      ? self
11864
      : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
11865
;
11866
11867
$.fn.progress = function(parameters) {
11868
  var
11869
    $allModules    = $(this),
11870
11871
    moduleSelector = $allModules.selector || '',
11872
11873
    time           = new Date().getTime(),
11874
    performance    = [],
11875
11876
    query          = arguments[0],
11877
    methodInvoked  = (typeof query == 'string'),
11878
    queryArguments = [].slice.call(arguments, 1),
11879
11880
    returnedValue
11881
  ;
11882
11883
  $allModules
11884
    .each(function() {
11885
      var
11886
        settings          = ( $.isPlainObject(parameters) )
11887
          ? $.extend(true, {}, $.fn.progress.settings, parameters)
11888
          : $.extend({}, $.fn.progress.settings),
11889
11890
        className       = settings.className,
11891
        metadata        = settings.metadata,
11892
        namespace       = settings.namespace,
11893
        selector        = settings.selector,
11894
        error           = settings.error,
11895
11896
        eventNamespace  = '.' + namespace,
11897
        moduleNamespace = 'module-' + namespace,
11898
11899
        $module         = $(this),
11900
        $bar            = $(this).find(selector.bar),
11901
        $progress       = $(this).find(selector.progress),
11902
        $label          = $(this).find(selector.label),
11903
11904
        element         = this,
11905
        instance        = $module.data(moduleNamespace),
11906
11907
        animating = false,
11908
        transitionEnd,
11909
        module
11910
      ;
11911
11912
      module = {
11913
11914
        initialize: function() {
11915
          module.debug('Initializing progress bar', settings);
11916
11917
          module.set.duration();
11918
          module.set.transitionEvent();
11919
11920
          module.read.metadata();
11921
          module.read.settings();
11922
11923
          module.instantiate();
11924
        },
11925
11926
        instantiate: function() {
11927
          module.verbose('Storing instance of progress', module);
11928
          instance = module;
11929
          $module
11930
            .data(moduleNamespace, module)
11931
          ;
11932
        },
11933
        destroy: function() {
11934
          module.verbose('Destroying previous progress for', $module);
11935
          clearInterval(instance.interval);
11936
          module.remove.state();
11937
          $module.removeData(moduleNamespace);
11938
          instance = undefined;
11939
        },
11940
11941
        reset: function() {
11942
          module.remove.nextValue();
11943
          module.update.progress(0);
11944
        },
11945
11946
        complete: function() {
11947
          if(module.percent === undefined || module.percent < 100) {
11948
            module.remove.progressPoll();
11949
            module.set.percent(100);
11950
          }
11951
        },
11952
11953
        read: {
11954
          metadata: function() {
11955
            var
11956
              data = {
11957
                percent : $module.data(metadata.percent),
11958
                total   : $module.data(metadata.total),
11959
                value   : $module.data(metadata.value)
11960
              }
11961
            ;
11962
            if(data.percent) {
11963
              module.debug('Current percent value set from metadata', data.percent);
11964
              module.set.percent(data.percent);
11965
            }
11966
            if(data.total) {
11967
              module.debug('Total value set from metadata', data.total);
11968
              module.set.total(data.total);
11969
            }
11970
            if(data.value) {
11971
              module.debug('Current value set from metadata', data.value);
11972
              module.set.value(data.value);
11973
              module.set.progress(data.value);
11974
            }
11975
          },
11976
          settings: function() {
11977
            if(settings.total !== false) {
11978
              module.debug('Current total set in settings', settings.total);
11979
              module.set.total(settings.total);
11980
            }
11981
            if(settings.value !== false) {
11982
              module.debug('Current value set in settings', settings.value);
11983
              module.set.value(settings.value);
11984
              module.set.progress(module.value);
11985
            }
11986
            if(settings.percent !== false) {
11987
              module.debug('Current percent set in settings', settings.percent);
11988
              module.set.percent(settings.percent);
11989
            }
11990
          }
11991
        },
11992
11993
        bind: {
11994
          transitionEnd: function(callback) {
11995
            var
11996
              transitionEnd = module.get.transitionEnd()
11997
            ;
11998
            $bar
11999
              .one(transitionEnd + eventNamespace, function(event) {
12000
                clearTimeout(module.failSafeTimer);
12001
                callback.call(this, event);
12002
              })
12003
            ;
12004
            module.failSafeTimer = setTimeout(function() {
12005
              $bar.triggerHandler(transitionEnd);
12006
            }, settings.duration + settings.failSafeDelay);
12007
            module.verbose('Adding fail safe timer', module.timer);
12008
          }
12009
        },
12010
12011
        increment: function(incrementValue) {
12012
          var
12013
            maxValue,
12014
            startValue,
12015
            newValue
12016
          ;
12017
          if( module.has.total() ) {
12018
            startValue     = module.get.value();
12019
            incrementValue = incrementValue || 1;
12020
            newValue       = startValue + incrementValue;
12021
          }
12022
          else {
12023
            startValue     = module.get.percent();
12024
            incrementValue = incrementValue || module.get.randomValue();
12025
12026
            newValue       = startValue + incrementValue;
12027
            maxValue       = 100;
0 ignored issues
show
Unused Code introduced by
The variable maxValue seems to be never used. Consider removing it.
Loading history...
12028
            module.debug('Incrementing percentage by', startValue, newValue);
12029
          }
12030
          newValue = module.get.normalizedValue(newValue);
12031
          module.set.progress(newValue);
12032
        },
12033
        decrement: function(decrementValue) {
12034
          var
12035
            total     = module.get.total(),
12036
            startValue,
12037
            newValue
12038
          ;
12039
          if(total) {
12040
            startValue     =  module.get.value();
12041
            decrementValue =  decrementValue || 1;
12042
            newValue       =  startValue - decrementValue;
12043
            module.debug('Decrementing value by', decrementValue, startValue);
12044
          }
12045
          else {
12046
            startValue     =  module.get.percent();
12047
            decrementValue =  decrementValue || module.get.randomValue();
12048
            newValue       =  startValue - decrementValue;
12049
            module.debug('Decrementing percentage by', decrementValue, startValue);
12050
          }
12051
          newValue = module.get.normalizedValue(newValue);
12052
          module.set.progress(newValue);
12053
        },
12054
12055
        has: {
12056
          progressPoll: function() {
12057
            return module.progressPoll;
12058
          },
12059
          total: function() {
12060
            return (module.get.total() !== false);
12061
          }
12062
        },
12063
12064
        get: {
12065
          text: function(templateText) {
12066
            var
12067
              value   = module.value                || 0,
12068
              total   = module.total                || 0,
12069
              percent = (animating)
12070
                ? module.get.displayPercent()
12071
                : module.percent || 0,
12072
              left = (module.total > 0)
12073
                ? (total - value)
12074
                : (100 - percent)
12075
            ;
12076
            templateText = templateText || '';
12077
            templateText = templateText
12078
              .replace('{value}', value)
12079
              .replace('{total}', total)
12080
              .replace('{left}', left)
12081
              .replace('{percent}', percent)
12082
            ;
12083
            module.verbose('Adding variables to progress bar text', templateText);
12084
            return templateText;
12085
          },
12086
12087
          normalizedValue: function(value) {
12088
            if(value < 0) {
12089
              module.debug('Value cannot decrement below 0');
12090
              return 0;
12091
            }
12092
            if(module.has.total()) {
12093
              if(value > module.total) {
12094
                module.debug('Value cannot increment above total', module.total);
12095
                return module.total;
12096
              }
12097
            }
12098
            else if(value > 100 ) {
12099
              module.debug('Value cannot increment above 100 percent');
12100
              return 100;
12101
            }
12102
            return value;
12103
          },
12104
12105
          updateInterval: function() {
12106
            if(settings.updateInterval == 'auto') {
12107
              return settings.duration;
12108
            }
12109
            return settings.updateInterval;
12110
          },
12111
12112
          randomValue: function() {
12113
            module.debug('Generating random increment percentage');
12114
            return Math.floor((Math.random() * settings.random.max) + settings.random.min);
12115
          },
12116
12117
          numericValue: function(value) {
12118
            return (typeof value === 'string')
12119
              ? (value.replace(/[^\d.]/g, '') !== '')
12120
                ? +(value.replace(/[^\d.]/g, ''))
12121
                : false
12122
              : value
12123
            ;
12124
          },
12125
12126
          transitionEnd: function() {
12127
            var
12128
              element     = document.createElement('element'),
12129
              transitions = {
12130
                'transition'       :'transitionend',
12131
                'OTransition'      :'oTransitionEnd',
12132
                'MozTransition'    :'transitionend',
12133
                'WebkitTransition' :'webkitTransitionEnd'
12134
              },
12135
              transition
12136
            ;
12137
            for(transition in transitions){
12138
              if( element.style[transition] !== undefined ){
12139
                return transitions[transition];
12140
              }
12141
            }
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
12142
          },
12143
12144
          // gets current displayed percentage (if animating values this is the intermediary value)
12145
          displayPercent: function() {
12146
            var
12147
              barWidth       = $bar.width(),
12148
              totalWidth     = $module.width(),
12149
              minDisplay     = parseInt($bar.css('min-width'), 10),
12150
              displayPercent = (barWidth > minDisplay)
12151
                ? (barWidth / totalWidth * 100)
12152
                : module.percent
12153
            ;
12154
            return (settings.precision > 0)
12155
              ? Math.round(displayPercent * (10 * settings.precision)) / (10 * settings.precision)
12156
              : Math.round(displayPercent)
12157
            ;
12158
          },
12159
12160
          percent: function() {
12161
            return module.percent || 0;
12162
          },
12163
          value: function() {
12164
            return module.nextValue || module.value || 0;
12165
          },
12166
          total: function() {
12167
            return module.total || false;
12168
          }
12169
        },
12170
12171
        create: {
12172
          progressPoll: function() {
12173
            module.progressPoll = setTimeout(function() {
12174
              module.update.toNextValue();
12175
              module.remove.progressPoll();
12176
            }, module.get.updateInterval());
12177
          },
12178
        },
12179
12180
        is: {
12181
          complete: function() {
12182
            return module.is.success() || module.is.warning() || module.is.error();
12183
          },
12184
          success: function() {
12185
            return $module.hasClass(className.success);
12186
          },
12187
          warning: function() {
12188
            return $module.hasClass(className.warning);
12189
          },
12190
          error: function() {
12191
            return $module.hasClass(className.error);
12192
          },
12193
          active: function() {
12194
            return $module.hasClass(className.active);
12195
          },
12196
          visible: function() {
12197
            return $module.is(':visible');
12198
          }
12199
        },
12200
12201
        remove: {
12202
          progressPoll: function() {
12203
            module.verbose('Removing progress poll timer');
12204
            if(module.progressPoll) {
12205
              clearTimeout(module.progressPoll);
12206
              delete module.progressPoll;
12207
            }
12208
          },
12209
          nextValue: function() {
12210
            module.verbose('Removing progress value stored for next update');
12211
            delete module.nextValue;
12212
          },
12213
          state: function() {
12214
            module.verbose('Removing stored state');
12215
            delete module.total;
12216
            delete module.percent;
12217
            delete module.value;
12218
          },
12219
          active: function() {
12220
            module.verbose('Removing active state');
12221
            $module.removeClass(className.active);
12222
          },
12223
          success: function() {
12224
            module.verbose('Removing success state');
12225
            $module.removeClass(className.success);
12226
          },
12227
          warning: function() {
12228
            module.verbose('Removing warning state');
12229
            $module.removeClass(className.warning);
12230
          },
12231
          error: function() {
12232
            module.verbose('Removing error state');
12233
            $module.removeClass(className.error);
12234
          }
12235
        },
12236
12237
        set: {
12238
          barWidth: function(value) {
12239
            if(value > 100) {
12240
              module.error(error.tooHigh, value);
12241
            }
12242
            else if (value < 0) {
12243
              module.error(error.tooLow, value);
12244
            }
12245
            else {
12246
              $bar
12247
                .css('width', value + '%')
12248
              ;
12249
              $module
12250
                .attr('data-percent', parseInt(value, 10))
12251
              ;
12252
            }
12253
          },
12254
          duration: function(duration) {
12255
            duration = duration || settings.duration;
12256
            duration = (typeof duration == 'number')
12257
              ? duration + 'ms'
12258
              : duration
12259
            ;
12260
            module.verbose('Setting progress bar transition duration', duration);
12261
            $bar
12262
              .css({
12263
                'transition-duration':  duration
12264
              })
12265
            ;
12266
          },
12267
          percent: function(percent) {
12268
            percent = (typeof percent == 'string')
12269
              ? +(percent.replace('%', ''))
12270
              : percent
12271
            ;
12272
            // round display percentage
12273
            percent = (settings.precision > 0)
12274
              ? Math.round(percent * (10 * settings.precision)) / (10 * settings.precision)
12275
              : Math.round(percent)
12276
            ;
12277
            module.percent = percent;
12278
            if( !module.has.total() ) {
12279
              module.value = (settings.precision > 0)
12280
                ? Math.round( (percent / 100) * module.total * (10 * settings.precision)) / (10 * settings.precision)
12281
                : Math.round( (percent / 100) * module.total * 10) / 10
12282
              ;
12283
              if(settings.limitValues) {
12284
                module.value = (module.value > 100)
12285
                  ? 100
12286
                  : (module.value < 0)
12287
                    ? 0
12288
                    : module.value
12289
                ;
12290
              }
12291
            }
12292
            module.set.barWidth(percent);
12293
            module.set.labelInterval();
12294
            module.set.labels();
12295
            settings.onChange.call(element, percent, module.value, module.total);
12296
          },
12297
          labelInterval: function() {
12298
            var
12299
              animationCallback = function() {
12300
                module.verbose('Bar finished animating, removing continuous label updates');
12301
                clearInterval(module.interval);
12302
                animating = false;
12303
                module.set.labels();
12304
              }
12305
            ;
12306
            clearInterval(module.interval);
12307
            module.bind.transitionEnd(animationCallback);
12308
            animating = true;
12309
            module.interval = setInterval(function() {
12310
              var
12311
                isInDOM = $.contains(document.documentElement, element)
12312
              ;
12313
              if(!isInDOM) {
12314
                clearInterval(module.interval);
12315
                animating = false;
12316
              }
12317
              module.set.labels();
12318
            }, settings.framerate);
12319
          },
12320
          labels: function() {
12321
            module.verbose('Setting both bar progress and outer label text');
12322
            module.set.barLabel();
12323
            module.set.state();
12324
          },
12325
          label: function(text) {
12326
            text = text || '';
12327
            if(text) {
12328
              text = module.get.text(text);
12329
              module.verbose('Setting label to text', text);
12330
              $label.text(text);
12331
            }
12332
          },
12333
          state: function(percent) {
12334
            percent = (percent !== undefined)
12335
              ? percent
12336
              : module.percent
12337
            ;
12338
            if(percent === 100) {
12339
              if(settings.autoSuccess && !(module.is.warning() || module.is.error() || module.is.success())) {
12340
                module.set.success();
12341
                module.debug('Automatically triggering success at 100%');
12342
              }
12343
              else {
12344
                module.verbose('Reached 100% removing active state');
12345
                module.remove.active();
12346
                module.remove.progressPoll();
12347
              }
12348
            }
12349
            else if(percent > 0) {
12350
              module.verbose('Adjusting active progress bar label', percent);
12351
              module.set.active();
12352
            }
12353
            else {
12354
              module.remove.active();
12355
              module.set.label(settings.text.active);
12356
            }
12357
          },
12358
          barLabel: function(text) {
12359
            if(text !== undefined) {
12360
              $progress.text( module.get.text(text) );
12361
            }
12362
            else if(settings.label == 'ratio' && module.total) {
12363
              module.verbose('Adding ratio to bar label');
12364
              $progress.text( module.get.text(settings.text.ratio) );
12365
            }
12366
            else if(settings.label == 'percent') {
12367
              module.verbose('Adding percentage to bar label');
12368
              $progress.text( module.get.text(settings.text.percent) );
12369
            }
12370
          },
12371
          active: function(text) {
12372
            text = text || settings.text.active;
12373
            module.debug('Setting active state');
12374
            if(settings.showActivity && !module.is.active() ) {
12375
              $module.addClass(className.active);
12376
            }
12377
            module.remove.warning();
12378
            module.remove.error();
12379
            module.remove.success();
12380
            text = settings.onLabelUpdate('active', text, module.value, module.total);
12381
            if(text) {
12382
              module.set.label(text);
12383
            }
12384
            module.bind.transitionEnd(function() {
12385
              settings.onActive.call(element, module.value, module.total);
12386
            });
12387
          },
12388
          success : function(text) {
12389
            text = text || settings.text.success || settings.text.active;
12390
            module.debug('Setting success state');
12391
            $module.addClass(className.success);
12392
            module.remove.active();
12393
            module.remove.warning();
12394
            module.remove.error();
12395
            module.complete();
12396
            if(settings.text.success) {
12397
              text = settings.onLabelUpdate('success', text, module.value, module.total);
12398
              module.set.label(text);
12399
            }
12400
            else {
12401
              text = settings.onLabelUpdate('active', text, module.value, module.total);
12402
              module.set.label(text);
12403
            }
12404
            module.bind.transitionEnd(function() {
12405
              settings.onSuccess.call(element, module.total);
12406
            });
12407
          },
12408
          warning : function(text) {
12409
            text = text || settings.text.warning;
12410
            module.debug('Setting warning state');
12411
            $module.addClass(className.warning);
12412
            module.remove.active();
12413
            module.remove.success();
12414
            module.remove.error();
12415
            module.complete();
12416
            text = settings.onLabelUpdate('warning', text, module.value, module.total);
12417
            if(text) {
12418
              module.set.label(text);
12419
            }
12420
            module.bind.transitionEnd(function() {
12421
              settings.onWarning.call(element, module.value, module.total);
12422
            });
12423
          },
12424
          error : function(text) {
12425
            text = text || settings.text.error;
12426
            module.debug('Setting error state');
12427
            $module.addClass(className.error);
12428
            module.remove.active();
12429
            module.remove.success();
12430
            module.remove.warning();
12431
            module.complete();
12432
            text = settings.onLabelUpdate('error', text, module.value, module.total);
12433
            if(text) {
12434
              module.set.label(text);
12435
            }
12436
            module.bind.transitionEnd(function() {
12437
              settings.onError.call(element, module.value, module.total);
12438
            });
12439
          },
12440
          transitionEvent: function() {
12441
            transitionEnd = module.get.transitionEnd();
12442
          },
12443
          total: function(totalValue) {
12444
            module.total = totalValue;
12445
          },
12446
          value: function(value) {
12447
            module.value = value;
12448
          },
12449
          progress: function(value) {
12450
            if(!module.has.progressPoll()) {
12451
              module.debug('First update in progress update interval, immediately updating', value);
12452
              module.update.progress(value);
12453
              module.create.progressPoll();
12454
            }
12455
            else {
12456
              module.debug('Updated within interval, setting next update to use new value', value);
12457
              module.set.nextValue(value);
12458
            }
12459
          },
12460
          nextValue: function(value) {
12461
            module.nextValue = value;
12462
          }
12463
        },
12464
12465
        update: {
12466
          toNextValue: function() {
12467
            var
12468
              nextValue = module.nextValue
12469
            ;
12470
            if(nextValue) {
12471
              module.debug('Update interval complete using last updated value', nextValue);
12472
              module.update.progress(nextValue);
12473
              module.remove.nextValue();
12474
            }
12475
          },
12476
          progress: function(value) {
12477
            var
12478
              percentComplete
12479
            ;
12480
            value = module.get.numericValue(value);
12481
            if(value === false) {
12482
              module.error(error.nonNumeric, value);
12483
            }
12484
            value = module.get.normalizedValue(value);
12485
            if( module.has.total() ) {
12486
              module.set.value(value);
12487
              percentComplete = (value / module.total) * 100;
12488
              module.debug('Calculating percent complete from total', percentComplete);
12489
              module.set.percent( percentComplete );
12490
            }
12491
            else {
12492
              percentComplete = value;
12493
              module.debug('Setting value to exact percentage value', percentComplete);
12494
              module.set.percent( percentComplete );
12495
            }
12496
          }
12497
        },
12498
12499
        setting: function(name, value) {
12500
          module.debug('Changing setting', name, value);
12501
          if( $.isPlainObject(name) ) {
12502
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
12503
          }
12504
          else if(value !== undefined) {
12505
            if($.isPlainObject(settings[name])) {
12506
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
12507
            }
12508
            else {
12509
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
12510
            }
12511
          }
12512
          else {
12513
            return settings[name];
12514
          }
12515
        },
12516
        internal: function(name, value) {
12517
          if( $.isPlainObject(name) ) {
12518
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
12519
          }
12520
          else if(value !== undefined) {
12521
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
12522
          }
12523
          else {
12524
            return module[name];
12525
          }
12526
        },
12527
        debug: function() {
12528
          if(!settings.silent && settings.debug) {
12529
            if(settings.performance) {
12530
              module.performance.log(arguments);
12531
            }
12532
            else {
12533
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
12534
              module.debug.apply(console, arguments);
12535
            }
12536
          }
12537
        },
12538
        verbose: function() {
12539
          if(!settings.silent && settings.verbose && settings.debug) {
12540
            if(settings.performance) {
12541
              module.performance.log(arguments);
12542
            }
12543
            else {
12544
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
12545
              module.verbose.apply(console, arguments);
12546
            }
12547
          }
12548
        },
12549
        error: function() {
12550
          if(!settings.silent) {
12551
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
12552
            module.error.apply(console, arguments);
12553
          }
12554
        },
12555
        performance: {
12556
          log: function(message) {
12557
            var
12558
              currentTime,
12559
              executionTime,
12560
              previousTime
12561
            ;
12562
            if(settings.performance) {
12563
              currentTime   = new Date().getTime();
12564
              previousTime  = time || currentTime;
12565
              executionTime = currentTime - previousTime;
12566
              time          = currentTime;
12567
              performance.push({
12568
                'Name'           : message[0],
12569
                'Arguments'      : [].slice.call(message, 1) || '',
12570
                'Element'        : element,
12571
                'Execution Time' : executionTime
12572
              });
12573
            }
12574
            clearTimeout(module.performance.timer);
12575
            module.performance.timer = setTimeout(module.performance.display, 500);
12576
          },
12577
          display: function() {
12578
            var
12579
              title = settings.name + ':',
12580
              totalTime = 0
12581
            ;
12582
            time = false;
12583
            clearTimeout(module.performance.timer);
12584
            $.each(performance, function(index, data) {
12585
              totalTime += data['Execution Time'];
12586
            });
12587
            title += ' ' + totalTime + 'ms';
12588
            if(moduleSelector) {
12589
              title += ' \'' + moduleSelector + '\'';
12590
            }
12591
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
12592
              console.groupCollapsed(title);
12593
              if(console.table) {
12594
                console.table(performance);
12595
              }
12596
              else {
12597
                $.each(performance, function(index, data) {
12598
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
12599
                });
12600
              }
12601
              console.groupEnd();
12602
            }
12603
            performance = [];
12604
          }
12605
        },
12606
        invoke: function(query, passedArguments, context) {
12607
          var
12608
            object = instance,
12609
            maxDepth,
12610
            found,
12611
            response
12612
          ;
12613
          passedArguments = passedArguments || queryArguments;
12614
          context         = element         || context;
12615
          if(typeof query == 'string' && object !== undefined) {
12616
            query    = query.split(/[\. ]/);
12617
            maxDepth = query.length - 1;
12618
            $.each(query, function(depth, value) {
12619
              var camelCaseValue = (depth != maxDepth)
12620
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
12621
                : query
12622
              ;
12623
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
12624
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
12625
              }
12626
              else if( object[camelCaseValue] !== undefined ) {
12627
                found = object[camelCaseValue];
12628
                return false;
12629
              }
12630
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
12631
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
12632
              }
12633
              else if( object[value] !== undefined ) {
12634
                found = object[value];
12635
                return false;
12636
              }
12637
              else {
12638
                module.error(error.method, query);
12639
                return false;
12640
              }
12641
            });
12642
          }
12643
          if ( $.isFunction( found ) ) {
12644
            response = found.apply(context, passedArguments);
12645
          }
12646
          else if(found !== undefined) {
12647
            response = found;
12648
          }
12649
          if($.isArray(returnedValue)) {
12650
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 12646 is false. Are you sure the function push handles undefined variables?
Loading history...
12651
          }
12652
          else if(returnedValue !== undefined) {
12653
            returnedValue = [returnedValue, response];
12654
          }
12655
          else if(response !== undefined) {
12656
            returnedValue = response;
12657
          }
12658
          return found;
12659
        }
12660
      };
12661
12662
      if(methodInvoked) {
12663
        if(instance === undefined) {
12664
          module.initialize();
12665
        }
12666
        module.invoke(query);
12667
      }
12668
      else {
12669
        if(instance !== undefined) {
12670
          instance.invoke('destroy');
12671
        }
12672
        module.initialize();
12673
      }
12674
    })
12675
  ;
12676
12677
  return (returnedValue !== undefined)
12678
    ? returnedValue
12679
    : this
12680
  ;
12681
};
12682
12683
$.fn.progress.settings = {
12684
12685
  name         : 'Progress',
12686
  namespace    : 'progress',
12687
12688
  silent       : false,
12689
  debug        : false,
12690
  verbose      : false,
12691
  performance  : true,
12692
12693
  random       : {
12694
    min : 2,
12695
    max : 5
12696
  },
12697
12698
  duration       : 300,
12699
12700
  updateInterval : 'auto',
12701
12702
  autoSuccess    : true,
12703
  showActivity   : true,
12704
  limitValues    : true,
12705
12706
  label          : 'percent',
12707
  precision      : 0,
12708
  framerate      : (1000 / 30), /// 30 fps
12709
12710
  percent        : false,
12711
  total          : false,
12712
  value          : false,
12713
12714
  // delay in ms for fail safe animation callback
12715
  failSafeDelay : 100,
12716
12717
  onLabelUpdate : function(state, text, value, total){
0 ignored issues
show
Unused Code introduced by
The parameter total is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
12718
    return text;
12719
  },
12720
  onChange      : function(percent, value, total){},
0 ignored issues
show
Unused Code introduced by
The parameter percent is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter total is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
12721
  onSuccess     : function(total){},
0 ignored issues
show
Unused Code introduced by
The parameter total is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
12722
  onActive      : function(value, total){},
0 ignored issues
show
Unused Code introduced by
The parameter total is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
12723
  onError       : function(value, total){},
0 ignored issues
show
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter total is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
12724
  onWarning     : function(value, total){},
0 ignored issues
show
Unused Code introduced by
The parameter total is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
12725
12726
  error    : {
12727
    method     : 'The method you called is not defined.',
12728
    nonNumeric : 'Progress value is non numeric',
12729
    tooHigh    : 'Value specified is above 100%',
12730
    tooLow     : 'Value specified is below 0%'
12731
  },
12732
12733
  regExp: {
12734
    variable: /\{\$*[A-z0-9]+\}/g
12735
  },
12736
12737
  metadata: {
12738
    percent : 'percent',
12739
    total   : 'total',
12740
    value   : 'value'
12741
  },
12742
12743
  selector : {
12744
    bar      : '> .bar',
12745
    label    : '> .label',
12746
    progress : '.bar > .progress'
12747
  },
12748
12749
  text : {
12750
    active  : false,
12751
    error   : false,
12752
    success : false,
12753
    warning : false,
12754
    percent : '{percent}%',
12755
    ratio   : '{value} of {total}'
12756
  },
12757
12758
  className : {
12759
    active  : 'active',
12760
    error   : 'error',
12761
    success : 'success',
12762
    warning : 'warning'
12763
  }
12764
12765
};
12766
12767
12768
})( jQuery, window, document );
12769
12770
/*!
12771
 * # Semantic UI 2.2.11 - Rating
12772
 * http://github.com/semantic-org/semantic-ui/
12773
 *
12774
 *
12775
 * Released under the MIT license
12776
 * http://opensource.org/licenses/MIT
12777
 *
12778
 */
12779
12780 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
12781
12782
"use strict";
12783
12784
window = (typeof window != 'undefined' && window.Math == Math)
0 ignored issues
show
Unused Code introduced by
The assignment to variable window seems to be never used. Consider removing it.
Loading history...
12785
  ? window
12786
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
12787
    ? self
12788
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
12789
;
12790
12791
$.fn.rating = function(parameters) {
12792
  var
12793
    $allModules     = $(this),
12794
    moduleSelector  = $allModules.selector || '',
12795
12796
    time            = new Date().getTime(),
12797
    performance     = [],
12798
12799
    query           = arguments[0],
12800
    methodInvoked   = (typeof query == 'string'),
12801
    queryArguments  = [].slice.call(arguments, 1),
12802
    returnedValue
12803
  ;
12804
  $allModules
12805
    .each(function() {
12806
      var
12807
        settings        = ( $.isPlainObject(parameters) )
12808
          ? $.extend(true, {}, $.fn.rating.settings, parameters)
12809
          : $.extend({}, $.fn.rating.settings),
12810
12811
        namespace       = settings.namespace,
12812
        className       = settings.className,
12813
        metadata        = settings.metadata,
12814
        selector        = settings.selector,
12815
        error           = settings.error,
12816
12817
        eventNamespace  = '.' + namespace,
12818
        moduleNamespace = 'module-' + namespace,
12819
12820
        element         = this,
12821
        instance        = $(this).data(moduleNamespace),
12822
12823
        $module         = $(this),
12824
        $icon           = $module.find(selector.icon),
12825
12826
        initialLoad,
12827
        module
12828
      ;
12829
12830
      module = {
12831
12832
        initialize: function() {
12833
          module.verbose('Initializing rating module', settings);
12834
12835
          if($icon.length === 0) {
12836
            module.setup.layout();
12837
          }
12838
12839
          if(settings.interactive) {
12840
            module.enable();
12841
          }
12842
          else {
12843
            module.disable();
12844
          }
12845
          module.set.initialLoad();
12846
          module.set.rating( module.get.initialRating() );
12847
          module.remove.initialLoad();
12848
          module.instantiate();
12849
        },
12850
12851
        instantiate: function() {
12852
          module.verbose('Instantiating module', settings);
12853
          instance = module;
12854
          $module
12855
            .data(moduleNamespace, module)
12856
          ;
12857
        },
12858
12859
        destroy: function() {
12860
          module.verbose('Destroying previous instance', instance);
12861
          module.remove.events();
12862
          $module
12863
            .removeData(moduleNamespace)
12864
          ;
12865
        },
12866
12867
        refresh: function() {
12868
          $icon   = $module.find(selector.icon);
12869
        },
12870
12871
        setup: {
12872
          layout: function() {
12873
            var
12874
              maxRating = module.get.maxRating(),
12875
              html      = $.fn.rating.settings.templates.icon(maxRating)
12876
            ;
12877
            module.debug('Generating icon html dynamically');
12878
            $module
12879
              .html(html)
12880
            ;
12881
            module.refresh();
12882
          }
12883
        },
12884
12885
        event: {
12886
          mouseenter: function() {
12887
            var
12888
              $activeIcon = $(this)
12889
            ;
12890
            $activeIcon
12891
              .nextAll()
12892
                .removeClass(className.selected)
12893
            ;
12894
            $module
12895
              .addClass(className.selected)
12896
            ;
12897
            $activeIcon
12898
              .addClass(className.selected)
12899
                .prevAll()
12900
                .addClass(className.selected)
12901
            ;
12902
          },
12903
          mouseleave: function() {
12904
            $module
12905
              .removeClass(className.selected)
12906
            ;
12907
            $icon
12908
              .removeClass(className.selected)
12909
            ;
12910
          },
12911
          click: function() {
12912
            var
12913
              $activeIcon   = $(this),
12914
              currentRating = module.get.rating(),
12915
              rating        = $icon.index($activeIcon) + 1,
12916
              canClear      = (settings.clearable == 'auto')
12917
               ? ($icon.length === 1)
12918
               : settings.clearable
12919
            ;
12920
            if(canClear && currentRating == rating) {
12921
              module.clearRating();
12922
            }
12923
            else {
12924
              module.set.rating( rating );
12925
            }
12926
          }
12927
        },
12928
12929
        clearRating: function() {
12930
          module.debug('Clearing current rating');
12931
          module.set.rating(0);
12932
        },
12933
12934
        bind: {
12935
          events: function() {
12936
            module.verbose('Binding events');
12937
            $module
12938
              .on('mouseenter' + eventNamespace, selector.icon, module.event.mouseenter)
12939
              .on('mouseleave' + eventNamespace, selector.icon, module.event.mouseleave)
12940
              .on('click'      + eventNamespace, selector.icon, module.event.click)
12941
            ;
12942
          }
12943
        },
12944
12945
        remove: {
12946
          events: function() {
12947
            module.verbose('Removing events');
12948
            $module
12949
              .off(eventNamespace)
12950
            ;
12951
          },
12952
          initialLoad: function() {
12953
            initialLoad = false;
12954
          }
12955
        },
12956
12957
        enable: function() {
12958
          module.debug('Setting rating to interactive mode');
12959
          module.bind.events();
12960
          $module
12961
            .removeClass(className.disabled)
12962
          ;
12963
        },
12964
12965
        disable: function() {
12966
          module.debug('Setting rating to read-only mode');
12967
          module.remove.events();
12968
          $module
12969
            .addClass(className.disabled)
12970
          ;
12971
        },
12972
12973
        is: {
12974
          initialLoad: function() {
12975
            return initialLoad;
12976
          }
12977
        },
12978
12979
        get: {
12980
          initialRating: function() {
12981
            if($module.data(metadata.rating) !== undefined) {
12982
              $module.removeData(metadata.rating);
12983
              return $module.data(metadata.rating);
12984
            }
12985
            return settings.initialRating;
12986
          },
12987
          maxRating: function() {
12988
            if($module.data(metadata.maxRating) !== undefined) {
12989
              $module.removeData(metadata.maxRating);
12990
              return $module.data(metadata.maxRating);
12991
            }
12992
            return settings.maxRating;
12993
          },
12994
          rating: function() {
12995
            var
12996
              currentRating = $icon.filter('.' + className.active).length
12997
            ;
12998
            module.verbose('Current rating retrieved', currentRating);
12999
            return currentRating;
13000
          }
13001
        },
13002
13003
        set: {
13004
          rating: function(rating) {
13005
            var
13006
              ratingIndex = (rating - 1 >= 0)
13007
                ? (rating - 1)
13008
                : 0,
13009
              $activeIcon = $icon.eq(ratingIndex)
13010
            ;
13011
            $module
13012
              .removeClass(className.selected)
13013
            ;
13014
            $icon
13015
              .removeClass(className.selected)
13016
              .removeClass(className.active)
13017
            ;
13018
            if(rating > 0) {
13019
              module.verbose('Setting current rating to', rating);
13020
              $activeIcon
13021
                .prevAll()
13022
                .addBack()
13023
                  .addClass(className.active)
13024
              ;
13025
            }
13026
            if(!module.is.initialLoad()) {
13027
              settings.onRate.call(element, rating);
13028
            }
13029
          },
13030
          initialLoad: function() {
13031
            initialLoad = true;
13032
          }
13033
        },
13034
13035
        setting: function(name, value) {
13036
          module.debug('Changing setting', name, value);
13037
          if( $.isPlainObject(name) ) {
13038
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
13039
          }
13040
          else if(value !== undefined) {
13041
            if($.isPlainObject(settings[name])) {
13042
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
13043
            }
13044
            else {
13045
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
13046
            }
13047
          }
13048
          else {
13049
            return settings[name];
13050
          }
13051
        },
13052
        internal: function(name, value) {
13053
          if( $.isPlainObject(name) ) {
13054
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
13055
          }
13056
          else if(value !== undefined) {
13057
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
13058
          }
13059
          else {
13060
            return module[name];
13061
          }
13062
        },
13063
        debug: function() {
13064
          if(!settings.silent && settings.debug) {
13065
            if(settings.performance) {
13066
              module.performance.log(arguments);
13067
            }
13068
            else {
13069
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
13070
              module.debug.apply(console, arguments);
13071
            }
13072
          }
13073
        },
13074
        verbose: function() {
13075
          if(!settings.silent && settings.verbose && settings.debug) {
13076
            if(settings.performance) {
13077
              module.performance.log(arguments);
13078
            }
13079
            else {
13080
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
13081
              module.verbose.apply(console, arguments);
13082
            }
13083
          }
13084
        },
13085
        error: function() {
13086
          if(!settings.silent) {
13087
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
13088
            module.error.apply(console, arguments);
13089
          }
13090
        },
13091
        performance: {
13092
          log: function(message) {
13093
            var
13094
              currentTime,
13095
              executionTime,
13096
              previousTime
13097
            ;
13098
            if(settings.performance) {
13099
              currentTime   = new Date().getTime();
13100
              previousTime  = time || currentTime;
13101
              executionTime = currentTime - previousTime;
13102
              time          = currentTime;
13103
              performance.push({
13104
                'Name'           : message[0],
13105
                'Arguments'      : [].slice.call(message, 1) || '',
13106
                'Element'        : element,
13107
                'Execution Time' : executionTime
13108
              });
13109
            }
13110
            clearTimeout(module.performance.timer);
13111
            module.performance.timer = setTimeout(module.performance.display, 500);
13112
          },
13113
          display: function() {
13114
            var
13115
              title = settings.name + ':',
13116
              totalTime = 0
13117
            ;
13118
            time = false;
13119
            clearTimeout(module.performance.timer);
13120
            $.each(performance, function(index, data) {
13121
              totalTime += data['Execution Time'];
13122
            });
13123
            title += ' ' + totalTime + 'ms';
13124
            if(moduleSelector) {
13125
              title += ' \'' + moduleSelector + '\'';
13126
            }
13127
            if($allModules.length > 1) {
13128
              title += ' ' + '(' + $allModules.length + ')';
13129
            }
13130
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
13131
              console.groupCollapsed(title);
13132
              if(console.table) {
13133
                console.table(performance);
13134
              }
13135
              else {
13136
                $.each(performance, function(index, data) {
13137
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
13138
                });
13139
              }
13140
              console.groupEnd();
13141
            }
13142
            performance = [];
13143
          }
13144
        },
13145
        invoke: function(query, passedArguments, context) {
13146
          var
13147
            object = instance,
13148
            maxDepth,
13149
            found,
13150
            response
13151
          ;
13152
          passedArguments = passedArguments || queryArguments;
13153
          context         = element         || context;
13154
          if(typeof query == 'string' && object !== undefined) {
13155
            query    = query.split(/[\. ]/);
13156
            maxDepth = query.length - 1;
13157
            $.each(query, function(depth, value) {
13158
              var camelCaseValue = (depth != maxDepth)
13159
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
13160
                : query
13161
              ;
13162
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
13163
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
13164
              }
13165
              else if( object[camelCaseValue] !== undefined ) {
13166
                found = object[camelCaseValue];
13167
                return false;
13168
              }
13169
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
13170
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
13171
              }
13172
              else if( object[value] !== undefined ) {
13173
                found = object[value];
13174
                return false;
13175
              }
13176
              else {
13177
                return false;
13178
              }
13179
            });
13180
          }
13181
          if ( $.isFunction( found ) ) {
13182
            response = found.apply(context, passedArguments);
13183
          }
13184
          else if(found !== undefined) {
13185
            response = found;
13186
          }
13187
          if($.isArray(returnedValue)) {
13188
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 13184 is false. Are you sure the function push handles undefined variables?
Loading history...
13189
          }
13190
          else if(returnedValue !== undefined) {
13191
            returnedValue = [returnedValue, response];
13192
          }
13193
          else if(response !== undefined) {
13194
            returnedValue = response;
13195
          }
13196
          return found;
13197
        }
13198
      };
13199
      if(methodInvoked) {
13200
        if(instance === undefined) {
13201
          module.initialize();
13202
        }
13203
        module.invoke(query);
13204
      }
13205
      else {
13206
        if(instance !== undefined) {
13207
          instance.invoke('destroy');
13208
        }
13209
        module.initialize();
13210
      }
13211
    })
13212
  ;
13213
13214
  return (returnedValue !== undefined)
13215
    ? returnedValue
13216
    : this
13217
  ;
13218
};
13219
13220
$.fn.rating.settings = {
13221
13222
  name          : 'Rating',
13223
  namespace     : 'rating',
13224
13225
  slent         : false,
13226
  debug         : false,
13227
  verbose       : false,
13228
  performance   : true,
13229
13230
  initialRating : 0,
13231
  interactive   : true,
13232
  maxRating     : 4,
13233
  clearable     : 'auto',
13234
13235
  fireOnInit    : false,
13236
13237
  onRate        : function(rating){},
0 ignored issues
show
Unused Code introduced by
The parameter rating is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
13238
13239
  error         : {
13240
    method    : 'The method you called is not defined',
13241
    noMaximum : 'No maximum rating specified. Cannot generate HTML automatically'
13242
  },
13243
13244
13245
  metadata: {
13246
    rating    : 'rating',
13247
    maxRating : 'maxRating'
13248
  },
13249
13250
  className : {
13251
    active   : 'active',
13252
    disabled : 'disabled',
13253
    selected : 'selected',
13254
    loading  : 'loading'
13255
  },
13256
13257
  selector  : {
13258
    icon : '.icon'
13259
  },
13260
13261
  templates: {
13262
    icon: function(maxRating) {
13263
      var
13264
        icon = 1,
13265
        html = ''
13266
      ;
13267
      while(icon <= maxRating) {
13268
        html += '<i class="icon"></i>';
13269
        icon++;
13270
      }
13271
      return html;
13272
    }
13273
  }
13274
13275
};
13276
13277
})( jQuery, window, document );
13278
13279
/*!
13280
 * # Semantic UI 2.2.11 - Search
13281
 * http://github.com/semantic-org/semantic-ui/
13282
 *
13283
 *
13284
 * Released under the MIT license
13285
 * http://opensource.org/licenses/MIT
13286
 *
13287
 */
13288
13289 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
13290
13291
"use strict";
13292
13293
window = (typeof window != 'undefined' && window.Math == Math)
13294
  ? window
13295
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
13296
    ? self
13297
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
13298
;
13299
13300
$.fn.search = function(parameters) {
13301
  var
13302
    $allModules     = $(this),
13303
    moduleSelector  = $allModules.selector || '',
13304
13305
    time            = new Date().getTime(),
13306
    performance     = [],
13307
13308
    query           = arguments[0],
13309
    methodInvoked   = (typeof query == 'string'),
13310
    queryArguments  = [].slice.call(arguments, 1),
13311
    returnedValue
13312
  ;
13313
  $(this)
13314
    .each(function() {
13315
      var
13316
        settings          = ( $.isPlainObject(parameters) )
13317
          ? $.extend(true, {}, $.fn.search.settings, parameters)
13318
          : $.extend({}, $.fn.search.settings),
13319
13320
        className        = settings.className,
13321
        metadata         = settings.metadata,
13322
        regExp           = settings.regExp,
13323
        fields           = settings.fields,
13324
        selector         = settings.selector,
13325
        error            = settings.error,
13326
        namespace        = settings.namespace,
13327
13328
        eventNamespace   = '.' + namespace,
13329
        moduleNamespace  = namespace + '-module',
13330
13331
        $module          = $(this),
13332
        $prompt          = $module.find(selector.prompt),
13333
        $searchButton    = $module.find(selector.searchButton),
13334
        $results         = $module.find(selector.results),
13335
        $result          = $module.find(selector.result),
13336
        $category        = $module.find(selector.category),
0 ignored issues
show
Unused Code introduced by
The variable $category seems to be never used. Consider removing it.
Loading history...
13337
13338
        element          = this,
13339
        instance         = $module.data(moduleNamespace),
13340
13341
        disabledBubbled  = false,
13342
        resultsDismissed = false,
13343
13344
        module
13345
      ;
13346
13347
      module = {
13348
13349
        initialize: function() {
13350
          module.verbose('Initializing module');
13351
          module.determine.searchFields();
13352
          module.bind.events();
13353
          module.set.type();
13354
          module.create.results();
13355
          module.instantiate();
13356
        },
13357
        instantiate: function() {
13358
          module.verbose('Storing instance of module', module);
13359
          instance = module;
13360
          $module
13361
            .data(moduleNamespace, module)
13362
          ;
13363
        },
13364
        destroy: function() {
13365
          module.verbose('Destroying instance');
13366
          $module
13367
            .off(eventNamespace)
13368
            .removeData(moduleNamespace)
13369
          ;
13370
        },
13371
13372
        refresh: function() {
13373
          module.debug('Refreshing selector cache');
13374
          $prompt         = $module.find(selector.prompt);
13375
          $searchButton   = $module.find(selector.searchButton);
13376
          $category       = $module.find(selector.category);
0 ignored issues
show
Unused Code introduced by
The variable $category seems to be never used. Consider removing it.
Loading history...
13377
          $results        = $module.find(selector.results);
13378
          $result         = $module.find(selector.result);
13379
        },
13380
13381
        refreshResults: function() {
13382
          $results = $module.find(selector.results);
13383
          $result  = $module.find(selector.result);
13384
        },
13385
13386
        bind: {
13387
          events: function() {
13388
            module.verbose('Binding events to search');
13389
            if(settings.automatic) {
13390
              $module
13391
                .on(module.get.inputEvent() + eventNamespace, selector.prompt, module.event.input)
13392
              ;
13393
              $prompt
13394
                .attr('autocomplete', 'off')
13395
              ;
13396
            }
13397
            $module
13398
              // prompt
13399
              .on('focus'     + eventNamespace, selector.prompt, module.event.focus)
13400
              .on('blur'      + eventNamespace, selector.prompt, module.event.blur)
13401
              .on('keydown'   + eventNamespace, selector.prompt, module.handleKeyboard)
13402
              // search button
13403
              .on('click'     + eventNamespace, selector.searchButton, module.query)
13404
              // results
13405
              .on('mousedown' + eventNamespace, selector.results, module.event.result.mousedown)
13406
              .on('mouseup'   + eventNamespace, selector.results, module.event.result.mouseup)
13407
              .on('click'     + eventNamespace, selector.result,  module.event.result.click)
13408
            ;
13409
          }
13410
        },
13411
13412
        determine: {
13413
          searchFields: function() {
13414
            // this makes sure $.extend does not add specified search fields to default fields
13415
            // this is the only setting which should not extend defaults
13416
            if(parameters && parameters.searchFields !== undefined) {
13417
              settings.searchFields = parameters.searchFields;
13418
            }
13419
          }
13420
        },
13421
13422
        event: {
13423
          input: function() {
13424
            if(settings.searchDelay) {
13425
              clearTimeout(module.timer);
13426
              module.timer = setTimeout(function() {
13427
                if(module.is.focused()) {
13428
                  module.query();
13429
                }
13430
              }, settings.searchDelay);
13431
            }
13432
            else {
13433
              module.query();
13434
            }
13435
          },
13436
          focus: function() {
13437
            module.set.focus();
13438
            if(settings.searchOnFocus && module.has.minimumCharacters() ) {
13439
              module.query(function() {
13440
                if(module.can.show() ) {
13441
                  module.showResults();
13442
                }
13443
              });
13444
            }
13445
          },
13446
          blur: function(event) {
13447
            var
13448
              pageLostFocus = (document.activeElement === this),
13449
              callback      = function() {
13450
                module.cancel.query();
13451
                module.remove.focus();
13452
                module.timer = setTimeout(module.hideResults, settings.hideDelay);
13453
              }
13454
            ;
13455
            if(pageLostFocus) {
13456
              return;
13457
            }
13458
            resultsDismissed = false;
13459
            if(module.resultsClicked) {
13460
              module.debug('Determining if user action caused search to close');
13461
              $module
13462
                .one('click.close' + eventNamespace, selector.results, function(event) {
13463
                  if(module.is.inMessage(event) || disabledBubbled) {
13464
                    $prompt.focus();
13465
                    return;
13466
                  }
13467
                  disabledBubbled = false;
13468
                  if( !module.is.animating() && !module.is.hidden()) {
13469
                    callback();
13470
                  }
13471
                })
13472
              ;
13473
            }
13474
            else {
13475
              module.debug('Input blurred without user action, closing results');
13476
              callback();
13477
            }
13478
          },
13479
          result: {
13480
            mousedown: function() {
13481
              module.resultsClicked = true;
13482
            },
13483
            mouseup: function() {
13484
              module.resultsClicked = false;
13485
            },
13486
            click: function(event) {
13487
              module.debug('Search result selected');
13488
              var
13489
                $result = $(this),
13490
                $title  = $result.find(selector.title).eq(0),
13491
                $link   = $result.is('a[href]')
13492
                  ? $result
13493
                  : $result.find('a[href]').eq(0),
13494
                href    = $link.attr('href')   || false,
13495
                target  = $link.attr('target') || false,
13496
                title   = $title.html(),
0 ignored issues
show
Unused Code introduced by
The assignment to variable title seems to be never used. Consider removing it.
Loading history...
13497
                // title is used for result lookup
13498
                value   = ($title.length > 0)
13499
                  ? $title.text()
13500
                  : false,
13501
                results = module.get.results(),
13502
                result  = $result.data(metadata.result) || module.get.result(value, results),
13503
                returnedValue
0 ignored issues
show
Unused Code introduced by
The variable returnedValue seems to be never used. Consider removing it.
Loading history...
13504
              ;
13505
              if( $.isFunction(settings.onSelect) ) {
13506
                if(settings.onSelect.call(element, result, results) === false) {
13507
                  module.debug('Custom onSelect callback cancelled default select action');
13508
                  disabledBubbled = true;
13509
                  return;
13510
                }
13511
              }
13512
              module.hideResults();
13513
              if(value) {
13514
                module.set.value(value);
13515
              }
13516
              if(href) {
13517
                module.verbose('Opening search link found in result', $link);
13518
                if(target == '_blank' || event.ctrlKey) {
13519
                  window.open(href);
13520
                }
13521
                else {
13522
                  window.location.href = (href);
13523
                }
13524
              }
13525
            }
13526
          }
13527
        },
13528
        handleKeyboard: function(event) {
13529
          var
13530
            // force selector refresh
13531
            $result         = $module.find(selector.result),
13532
            $category       = $module.find(selector.category),
13533
            $activeResult   = $result.filter('.' + className.active),
13534
            currentIndex    = $result.index( $activeResult ),
13535
            resultSize      = $result.length,
13536
            hasActiveResult = $activeResult.length > 0,
13537
13538
            keyCode         = event.which,
13539
            keys            = {
13540
              backspace : 8,
13541
              enter     : 13,
13542
              escape    : 27,
13543
              upArrow   : 38,
13544
              downArrow : 40
13545
            },
13546
            newIndex
13547
          ;
13548
          // search shortcuts
13549
          if(keyCode == keys.escape) {
13550
            module.verbose('Escape key pressed, blurring search field');
13551
            module.hideResults();
13552
            resultsDismissed = true;
13553
          }
13554
          if( module.is.visible() ) {
13555
            if(keyCode == keys.enter) {
13556
              module.verbose('Enter key pressed, selecting active result');
13557
              if( $result.filter('.' + className.active).length > 0 ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if $result.filter("." + className.active).length > 0 is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
13558
                module.event.result.click.call($result.filter('.' + className.active), event);
13559
                event.preventDefault();
13560
                return false;
13561
              }
13562
            }
13563
            else if(keyCode == keys.upArrow && hasActiveResult) {
13564
              module.verbose('Up key pressed, changing active result');
13565
              newIndex = (currentIndex - 1 < 0)
13566
                ? currentIndex
13567
                : currentIndex - 1
13568
              ;
13569
              $category
13570
                .removeClass(className.active)
13571
              ;
13572
              $result
13573
                .removeClass(className.active)
13574
                .eq(newIndex)
13575
                  .addClass(className.active)
13576
                  .closest($category)
13577
                    .addClass(className.active)
13578
              ;
13579
              event.preventDefault();
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
13580
            }
13581
            else if(keyCode == keys.downArrow) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if keyCode == keys.downArrow is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
13582
              module.verbose('Down key pressed, changing active result');
13583
              newIndex = (currentIndex + 1 >= resultSize)
13584
                ? currentIndex
13585
                : currentIndex + 1
13586
              ;
13587
              $category
13588
                .removeClass(className.active)
13589
              ;
13590
              $result
13591
                .removeClass(className.active)
13592
                .eq(newIndex)
13593
                  .addClass(className.active)
13594
                  .closest($category)
13595
                    .addClass(className.active)
13596
              ;
13597
              event.preventDefault();
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
13598
            }
13599
          }
13600
          else {
13601
            // query shortcuts
13602
            if(keyCode == keys.enter) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if keyCode == keys.enter is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
13603
              module.verbose('Enter key pressed, executing query');
13604
              module.query();
13605
              module.set.buttonPressed();
13606
              $prompt.one('keyup', module.remove.buttonFocus);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
13607
            }
13608
          }
13609
        },
13610
13611
        setup: {
13612
          api: function(searchTerm, callback) {
13613
            var
13614
              apiSettings = {
13615
                debug             : settings.debug,
13616
                on                : false,
13617
                cache             : true,
13618
                action            : 'search',
13619
                urlData           : {
13620
                  query : searchTerm
13621
                },
13622
                onSuccess         : function(response) {
13623
                  module.parse.response.call(element, response, searchTerm);
13624
                  callback();
13625
                },
13626
                onFailure         : function() {
13627
                  module.displayMessage(error.serverError);
13628
                  callback();
13629
                },
13630
                onAbort : function(response) {
0 ignored issues
show
Unused Code introduced by
The parameter response is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
13631
                },
13632
                onError           : module.error
13633
              },
13634
              searchHTML
0 ignored issues
show
Unused Code introduced by
The variable searchHTML seems to be never used. Consider removing it.
Loading history...
13635
            ;
13636
            $.extend(true, apiSettings, settings.apiSettings);
13637
            module.verbose('Setting up API request', apiSettings);
13638
            $module.api(apiSettings);
13639
          }
13640
        },
13641
13642
        can: {
13643
          useAPI: function() {
13644
            return $.fn.api !== undefined;
13645
          },
13646
          show: function() {
13647
            return module.is.focused() && !module.is.visible() && !module.is.empty();
13648
          },
13649
          transition: function() {
13650
            return settings.transition && $.fn.transition !== undefined && $module.transition('is supported');
13651
          }
13652
        },
13653
13654
        is: {
13655
          animating: function() {
13656
            return $results.hasClass(className.animating);
13657
          },
13658
          hidden: function() {
13659
            return $results.hasClass(className.hidden);
13660
          },
13661
          inMessage: function(event) {
13662
            if(!event.target) {
13663
              return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
13664
            }
13665
            var
13666
              $target = $(event.target),
13667
              isInDOM = $.contains(document.documentElement, event.target)
13668
            ;
13669
            return (isInDOM && $target.closest(selector.message).length > 0);
13670
          },
13671
          empty: function() {
13672
            return ($results.html() === '');
13673
          },
13674
          visible: function() {
13675
            return ($results.filter(':visible').length > 0);
13676
          },
13677
          focused: function() {
13678
            return ($prompt.filter(':focus').length > 0);
13679
          }
13680
        },
13681
13682
        get: {
13683
          inputEvent: function() {
13684
            var
13685
              prompt = $prompt[0],
13686
              inputEvent   = (prompt !== undefined && prompt.oninput !== undefined)
13687
                ? 'input'
13688
                : (prompt !== undefined && prompt.onpropertychange !== undefined)
13689
                  ? 'propertychange'
13690
                  : 'keyup'
13691
            ;
13692
            return inputEvent;
13693
          },
13694
          value: function() {
13695
            return $prompt.val();
13696
          },
13697
          results: function() {
13698
            var
13699
              results = $module.data(metadata.results)
13700
            ;
13701
            return results;
13702
          },
13703
          result: function(value, results) {
13704
            var
13705
              lookupFields = ['title', 'id'],
13706
              result       = false
13707
            ;
13708
            value = (value !== undefined)
13709
              ? value
13710
              : module.get.value()
13711
            ;
13712
            results = (results !== undefined)
13713
              ? results
13714
              : module.get.results()
13715
            ;
13716
            if(settings.type === 'category') {
13717
              module.debug('Finding result that matches', value);
13718
              $.each(results, function(index, category) {
13719
                if($.isArray(category.results)) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if $.isArray(category.results) is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
13720
                  result = module.search.object(value, category.results, lookupFields)[0];
13721
                  // don't continue searching if a result is found
13722
                  if(result) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if result is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
13723
                    return false;
13724
                  }
13725
                }
13726
              });
13727
            }
13728
            else {
13729
              module.debug('Finding result in results object', value);
13730
              result = module.search.object(value, results, lookupFields)[0];
13731
            }
13732
            return result || false;
13733
          },
13734
        },
13735
13736
        select: {
13737
          firstResult: function() {
13738
            module.verbose('Selecting first result');
13739
            $result.first().addClass(className.active);
13740
          }
13741
        },
13742
13743
        set: {
13744
          focus: function() {
13745
            $module.addClass(className.focus);
13746
          },
13747
          loading: function() {
13748
            $module.addClass(className.loading);
13749
          },
13750
          value: function(value) {
13751
            module.verbose('Setting search input value', value);
13752
            $prompt
13753
              .val(value)
13754
            ;
13755
          },
13756
          type: function(type) {
13757
            type = type || settings.type;
13758
            if(settings.type == 'category') {
13759
              $module.addClass(settings.type);
13760
            }
13761
          },
13762
          buttonPressed: function() {
13763
            $searchButton.addClass(className.pressed);
13764
          }
13765
        },
13766
13767
        remove: {
13768
          loading: function() {
13769
            $module.removeClass(className.loading);
13770
          },
13771
          focus: function() {
13772
            $module.removeClass(className.focus);
13773
          },
13774
          buttonPressed: function() {
13775
            $searchButton.removeClass(className.pressed);
13776
          }
13777
        },
13778
13779
        query: function(callback) {
13780
          callback = $.isFunction(callback)
13781
            ? callback
13782
            : function(){}
13783
          ;
13784
          var
13785
            searchTerm = module.get.value(),
13786
            cache = module.read.cache(searchTerm)
13787
          ;
13788
          callback = callback || function() {};
13789
          if( module.has.minimumCharacters() )  {
13790
            if(cache) {
13791
              module.debug('Reading result from cache', searchTerm);
13792
              module.save.results(cache.results);
13793
              module.addResults(cache.html);
13794
              module.inject.id(cache.results);
13795
              callback();
13796
            }
13797
            else {
13798
              module.debug('Querying for', searchTerm);
13799
              if($.isPlainObject(settings.source) || $.isArray(settings.source)) {
13800
                module.search.local(searchTerm);
13801
                callback();
13802
              }
13803
              else if( module.can.useAPI() ) {
13804
                module.search.remote(searchTerm, callback);
13805
              }
13806
              else {
13807
                module.error(error.source);
13808
                callback();
13809
              }
13810
            }
13811
            settings.onSearchQuery.call(element, searchTerm);
13812
          }
13813
          else {
13814
            module.hideResults();
13815
          }
13816
        },
13817
13818
        search: {
13819
          local: function(searchTerm) {
13820
            var
13821
              results = module.search.object(searchTerm, settings.content),
13822
              searchHTML
13823
            ;
13824
            module.set.loading();
13825
            module.save.results(results);
13826
            module.debug('Returned local search results', results);
13827
13828
            searchHTML = module.generateResults({
13829
              results: results
13830
            });
13831
            module.remove.loading();
13832
            module.addResults(searchHTML);
13833
            module.inject.id(results);
13834
            module.write.cache(searchTerm, {
13835
              html    : searchHTML,
13836
              results : results
13837
            });
13838
          },
13839
          remote: function(searchTerm, callback) {
13840
            callback = $.isFunction(callback)
13841
              ? callback
13842
              : function(){}
13843
            ;
13844
            if($module.api('is loading')) {
13845
              $module.api('abort');
13846
            }
13847
            module.setup.api(searchTerm, callback);
13848
            $module
13849
              .api('query')
13850
            ;
13851
          },
13852
          object: function(searchTerm, source, searchFields) {
13853
            var
13854
              results      = [],
13855
              fuzzyResults = [],
13856
              searchExp    = searchTerm.toString().replace(regExp.escape, '\\$&'),
13857
              matchRegExp  = new RegExp(regExp.beginsWith + searchExp, 'i'),
13858
13859
              // avoid duplicates when pushing results
13860
              addResult = function(array, result) {
13861
                var
13862
                  notResult      = ($.inArray(result, results) == -1),
13863
                  notFuzzyResult = ($.inArray(result, fuzzyResults) == -1)
13864
                ;
13865
                if(notResult && notFuzzyResult) {
13866
                  array.push(result);
13867
                }
13868
              }
13869
            ;
13870
            source = source || settings.source;
13871
            searchFields = (searchFields !== undefined)
13872
              ? searchFields
13873
              : settings.searchFields
13874
            ;
13875
13876
            // search fields should be array to loop correctly
13877
            if(!$.isArray(searchFields)) {
13878
              searchFields = [searchFields];
13879
            }
13880
13881
            // exit conditions if no source
13882
            if(source === undefined || source === false) {
13883
              module.error(error.source);
13884
              return [];
13885
            }
13886
13887
            // iterate through search fields looking for matches
13888
            $.each(searchFields, function(index, field) {
13889
              $.each(source, function(label, content) {
13890
                var
13891
                  fieldExists = (typeof content[field] == 'string')
13892
                ;
13893
                if(fieldExists) {
13894
                  if( content[field].search(matchRegExp) !== -1) {
13895
                    // content starts with value (first in results)
13896
                    addResult(results, content);
13897
                  }
13898
                  else if(settings.searchFullText && module.fuzzySearch(searchTerm, content[field]) ) {
13899
                    // content fuzzy matches (last in results)
13900
                    addResult(fuzzyResults, content);
13901
                  }
13902
                }
13903
              });
13904
            });
13905
            return $.merge(results, fuzzyResults);
13906
          }
13907
        },
13908
13909
        fuzzySearch: function(query, term) {
13910
          var
13911
            termLength  = term.length,
13912
            queryLength = query.length
13913
          ;
13914
          if(typeof query !== 'string') {
13915
            return false;
13916
          }
13917
          query = query.toLowerCase();
13918
          term  = term.toLowerCase();
13919
          if(queryLength > termLength) {
13920
            return false;
13921
          }
13922
          if(queryLength === termLength) {
13923
            return (query === term);
13924
          }
13925
          search: for (var characterIndex = 0, nextCharacterIndex = 0; characterIndex < queryLength; characterIndex++) {
13926
            var
13927
              queryCharacter = query.charCodeAt(characterIndex)
13928
            ;
13929
            while(nextCharacterIndex < termLength) {
13930
              if(term.charCodeAt(nextCharacterIndex++) === queryCharacter) {
13931
                continue search;
13932
              }
13933
            }
13934
            return false;
13935
          }
13936
          return true;
13937
        },
13938
13939
        parse: {
13940
          response: function(response, searchTerm) {
13941
            var
13942
              searchHTML = module.generateResults(response)
13943
            ;
13944
            module.verbose('Parsing server response', response);
13945
            if(response !== undefined) {
13946
              if(searchTerm !== undefined && response[fields.results] !== undefined) {
13947
                module.addResults(searchHTML);
13948
                module.inject.id(response[fields.results]);
13949
                module.write.cache(searchTerm, {
13950
                  html    : searchHTML,
13951
                  results : response[fields.results]
13952
                });
13953
                module.save.results(response[fields.results]);
13954
              }
13955
            }
13956
          }
13957
        },
13958
13959
        cancel: {
13960
          query: function() {
13961
            if( module.can.useAPI() ) {
13962
              $module.api('abort');
13963
            }
13964
          }
13965
        },
13966
13967
        has: {
13968
          minimumCharacters: function() {
13969
            var
13970
              searchTerm    = module.get.value(),
13971
              numCharacters = searchTerm.length
13972
            ;
13973
            return (numCharacters >= settings.minCharacters);
13974
          },
13975
          results: function() {
13976
            if($results.length === 0) {
13977
              return false;
13978
            }
13979
            var
13980
              html = $results.html()
13981
            ;
13982
            return html != '';
13983
          }
13984
        },
13985
13986
        clear: {
13987
          cache: function(value) {
13988
            var
13989
              cache = $module.data(metadata.cache)
13990
            ;
13991
            if(!value) {
13992
              module.debug('Clearing cache', value);
13993
              $module.removeData(metadata.cache);
13994
            }
13995
            else if(value && cache && cache[value]) {
13996
              module.debug('Removing value from cache', value);
13997
              delete cache[value];
13998
              $module.data(metadata.cache, cache);
13999
            }
14000
          }
14001
        },
14002
14003
        read: {
14004
          cache: function(name) {
14005
            var
14006
              cache = $module.data(metadata.cache)
14007
            ;
14008
            if(settings.cache) {
14009
              module.verbose('Checking cache for generated html for query', name);
14010
              return (typeof cache == 'object') && (cache[name] !== undefined)
14011
                ? cache[name]
14012
                : false
14013
              ;
14014
            }
14015
            return false;
14016
          }
14017
        },
14018
14019
        create: {
14020
          id: function(resultIndex, categoryIndex) {
14021
            var
14022
              resultID      = (resultIndex + 1), // not zero indexed
14023
              categoryID    = (categoryIndex + 1),
0 ignored issues
show
Unused Code introduced by
The variable categoryID seems to be never used. Consider removing it.
Loading history...
14024
              firstCharCode,
0 ignored issues
show
Unused Code introduced by
The variable firstCharCode seems to be never used. Consider removing it.
Loading history...
14025
              letterID,
14026
              id
14027
            ;
14028
            if(categoryIndex !== undefined) {
14029
              // start char code for "A"
14030
              letterID = String.fromCharCode(97 + categoryIndex);
14031
              id          = letterID + resultID;
14032
              module.verbose('Creating category result id', id);
14033
            }
14034
            else {
14035
              id = resultID;
14036
              module.verbose('Creating result id', id);
14037
            }
14038
            return id;
14039
          },
14040
          results: function() {
14041
            if($results.length === 0) {
14042
              $results = $('<div />')
14043
                .addClass(className.results)
14044
                .appendTo($module)
14045
              ;
14046
            }
14047
          }
14048
        },
14049
14050
        inject: {
14051
          result: function(result, resultIndex, categoryIndex) {
14052
            module.verbose('Injecting result into results');
14053
            var
14054
              $selectedResult = (categoryIndex !== undefined)
14055
                ? $results
14056
                    .children().eq(categoryIndex)
14057
                      .children(selector.result).eq(resultIndex)
14058
                : $results
14059
                    .children(selector.result).eq(resultIndex)
14060
            ;
14061
            module.verbose('Injecting results metadata', $selectedResult);
14062
            $selectedResult
14063
              .data(metadata.result, result)
14064
            ;
14065
          },
14066
          id: function(results) {
14067
            module.debug('Injecting unique ids into results');
14068
            var
14069
              // since results may be object, we must use counters
14070
              categoryIndex = 0,
14071
              resultIndex   = 0
14072
            ;
14073
            if(settings.type === 'category') {
14074
              // iterate through each category result
14075
              $.each(results, function(index, category) {
14076
                resultIndex = 0;
14077
                $.each(category.results, function(index, value) {
0 ignored issues
show
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
14078
                  var
14079
                    result = category.results[index]
14080
                  ;
14081
                  if(result.id === undefined) {
14082
                    result.id = module.create.id(resultIndex, categoryIndex);
14083
                  }
14084
                  module.inject.result(result, resultIndex, categoryIndex);
14085
                  resultIndex++;
14086
                });
14087
                categoryIndex++;
14088
              });
14089
            }
14090
            else {
14091
              // top level
14092
              $.each(results, function(index, value) {
0 ignored issues
show
Unused Code introduced by
The parameter value is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
14093
                var
14094
                  result = results[index]
14095
                ;
14096
                if(result.id === undefined) {
14097
                  result.id = module.create.id(resultIndex);
14098
                }
14099
                module.inject.result(result, resultIndex);
14100
                resultIndex++;
14101
              });
14102
            }
14103
            return results;
14104
          }
14105
        },
14106
14107
        save: {
14108
          results: function(results) {
14109
            module.verbose('Saving current search results to metadata', results);
14110
            $module.data(metadata.results, results);
14111
          }
14112
        },
14113
14114
        write: {
14115
          cache: function(name, value) {
14116
            var
14117
              cache = ($module.data(metadata.cache) !== undefined)
14118
                ? $module.data(metadata.cache)
14119
                : {}
14120
            ;
14121
            if(settings.cache) {
14122
              module.verbose('Writing generated html to cache', name, value);
14123
              cache[name] = value;
14124
              $module
14125
                .data(metadata.cache, cache)
14126
              ;
14127
            }
14128
          }
14129
        },
14130
14131
        addResults: function(html) {
14132
          if( $.isFunction(settings.onResultsAdd) ) {
14133
            if( settings.onResultsAdd.call($results, html) === false ) {
14134
              module.debug('onResultsAdd callback cancelled default action');
14135
              return false;
14136
            }
14137
          }
14138
          if(html) {
14139
            $results
14140
              .html(html)
14141
            ;
14142
            module.refreshResults();
14143
            if(settings.selectFirstResult) {
14144
              module.select.firstResult();
14145
            }
14146
            module.showResults();
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
14147
          }
14148
          else {
14149
            module.hideResults(function() {
14150
              $results.empty();
14151
            });
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
14152
          }
14153
        },
14154
14155
        showResults: function(callback) {
14156
          callback = $.isFunction(callback)
14157
            ? callback
14158
            : function(){}
14159
          ;
14160
          if(resultsDismissed) {
14161
            return;
14162
          }
14163
          if(!module.is.visible() && module.has.results()) {
14164
            if( module.can.transition() ) {
14165
              module.debug('Showing results with css animations');
14166
              $results
14167
                .transition({
14168
                  animation  : settings.transition + ' in',
14169
                  debug      : settings.debug,
14170
                  verbose    : settings.verbose,
14171
                  duration   : settings.duration,
14172
                  onComplete : function() {
14173
                    callback();
14174
                  },
14175
                  queue      : true
14176
                })
14177
              ;
14178
            }
14179
            else {
14180
              module.debug('Showing results with javascript');
14181
              $results
14182
                .stop()
14183
                .fadeIn(settings.duration, settings.easing)
14184
              ;
14185
            }
14186
            settings.onResultsOpen.call($results);
14187
          }
14188
        },
14189
        hideResults: function(callback) {
14190
          callback = $.isFunction(callback)
14191
            ? callback
14192
            : function(){}
14193
          ;
14194
          if( module.is.visible() ) {
14195
            if( module.can.transition() ) {
14196
              module.debug('Hiding results with css animations');
14197
              $results
14198
                .transition({
14199
                  animation  : settings.transition + ' out',
14200
                  debug      : settings.debug,
14201
                  verbose    : settings.verbose,
14202
                  duration   : settings.duration,
14203
                  onComplete : function() {
14204
                    callback();
14205
                  },
14206
                  queue      : true
14207
                })
14208
              ;
14209
            }
14210
            else {
14211
              module.debug('Hiding results with javascript');
14212
              $results
14213
                .stop()
14214
                .fadeOut(settings.duration, settings.easing)
14215
              ;
14216
            }
14217
            settings.onResultsClose.call($results);
14218
          }
14219
        },
14220
14221
        generateResults: function(response) {
14222
          module.debug('Generating html from response', response);
14223
          var
14224
            template       = settings.templates[settings.type],
14225
            isProperObject = ($.isPlainObject(response[fields.results]) && !$.isEmptyObject(response[fields.results])),
14226
            isProperArray  = ($.isArray(response[fields.results]) && response[fields.results].length > 0),
14227
            html           = ''
14228
          ;
14229
          if(isProperObject || isProperArray ) {
14230
            if(settings.maxResults > 0) {
14231
              if(isProperObject) {
14232
                if(settings.type == 'standard') {
14233
                  module.error(error.maxResults);
14234
                }
14235
              }
14236
              else {
14237
                response[fields.results] = response[fields.results].slice(0, settings.maxResults);
14238
              }
14239
            }
14240
            if($.isFunction(template)) {
14241
              html = template(response, fields);
14242
            }
14243
            else {
14244
              module.error(error.noTemplate, false);
14245
            }
14246
          }
14247
          else if(settings.showNoResults) {
14248
            html = module.displayMessage(error.noResults, 'empty');
14249
          }
14250
          settings.onResults.call(element, response);
14251
          return html;
14252
        },
14253
14254
        displayMessage: function(text, type) {
14255
          type = type || 'standard';
14256
          module.debug('Displaying message', text, type);
14257
          module.addResults( settings.templates.message(text, type) );
14258
          return settings.templates.message(text, type);
14259
        },
14260
14261
        setting: function(name, value) {
14262
          if( $.isPlainObject(name) ) {
14263
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
14264
          }
14265
          else if(value !== undefined) {
14266
            settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
14267
          }
14268
          else {
14269
            return settings[name];
14270
          }
14271
        },
14272
        internal: function(name, value) {
14273
          if( $.isPlainObject(name) ) {
14274
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
14275
          }
14276
          else if(value !== undefined) {
14277
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
14278
          }
14279
          else {
14280
            return module[name];
14281
          }
14282
        },
14283
        debug: function() {
14284
          if(!settings.silent && settings.debug) {
14285
            if(settings.performance) {
14286
              module.performance.log(arguments);
14287
            }
14288
            else {
14289
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
14290
              module.debug.apply(console, arguments);
14291
            }
14292
          }
14293
        },
14294
        verbose: function() {
14295
          if(!settings.silent && settings.verbose && settings.debug) {
14296
            if(settings.performance) {
14297
              module.performance.log(arguments);
14298
            }
14299
            else {
14300
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
14301
              module.verbose.apply(console, arguments);
14302
            }
14303
          }
14304
        },
14305
        error: function() {
14306
          if(!settings.silent) {
14307
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
14308
            module.error.apply(console, arguments);
14309
          }
14310
        },
14311
        performance: {
14312
          log: function(message) {
14313
            var
14314
              currentTime,
14315
              executionTime,
14316
              previousTime
14317
            ;
14318
            if(settings.performance) {
14319
              currentTime   = new Date().getTime();
14320
              previousTime  = time || currentTime;
14321
              executionTime = currentTime - previousTime;
14322
              time          = currentTime;
14323
              performance.push({
14324
                'Name'           : message[0],
14325
                'Arguments'      : [].slice.call(message, 1) || '',
14326
                'Element'        : element,
14327
                'Execution Time' : executionTime
14328
              });
14329
            }
14330
            clearTimeout(module.performance.timer);
14331
            module.performance.timer = setTimeout(module.performance.display, 500);
14332
          },
14333
          display: function() {
14334
            var
14335
              title = settings.name + ':',
14336
              totalTime = 0
14337
            ;
14338
            time = false;
14339
            clearTimeout(module.performance.timer);
14340
            $.each(performance, function(index, data) {
14341
              totalTime += data['Execution Time'];
14342
            });
14343
            title += ' ' + totalTime + 'ms';
14344
            if(moduleSelector) {
14345
              title += ' \'' + moduleSelector + '\'';
14346
            }
14347
            if($allModules.length > 1) {
14348
              title += ' ' + '(' + $allModules.length + ')';
14349
            }
14350
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
14351
              console.groupCollapsed(title);
14352
              if(console.table) {
14353
                console.table(performance);
14354
              }
14355
              else {
14356
                $.each(performance, function(index, data) {
14357
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
14358
                });
14359
              }
14360
              console.groupEnd();
14361
            }
14362
            performance = [];
14363
          }
14364
        },
14365
        invoke: function(query, passedArguments, context) {
14366
          var
14367
            object = instance,
14368
            maxDepth,
14369
            found,
14370
            response
14371
          ;
14372
          passedArguments = passedArguments || queryArguments;
14373
          context         = element         || context;
14374
          if(typeof query == 'string' && object !== undefined) {
14375
            query    = query.split(/[\. ]/);
14376
            maxDepth = query.length - 1;
14377
            $.each(query, function(depth, value) {
14378
              var camelCaseValue = (depth != maxDepth)
14379
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
14380
                : query
14381
              ;
14382
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
14383
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
14384
              }
14385
              else if( object[camelCaseValue] !== undefined ) {
14386
                found = object[camelCaseValue];
14387
                return false;
14388
              }
14389
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
14390
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
14391
              }
14392
              else if( object[value] !== undefined ) {
14393
                found = object[value];
14394
                return false;
14395
              }
14396
              else {
14397
                return false;
14398
              }
14399
            });
14400
          }
14401
          if( $.isFunction( found ) ) {
14402
            response = found.apply(context, passedArguments);
14403
          }
14404
          else if(found !== undefined) {
14405
            response = found;
14406
          }
14407
          if($.isArray(returnedValue)) {
14408
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 14404 is false. Are you sure the function push handles undefined variables?
Loading history...
14409
          }
14410
          else if(returnedValue !== undefined) {
14411
            returnedValue = [returnedValue, response];
14412
          }
14413
          else if(response !== undefined) {
14414
            returnedValue = response;
14415
          }
14416
          return found;
14417
        }
14418
      };
14419
      if(methodInvoked) {
14420
        if(instance === undefined) {
14421
          module.initialize();
14422
        }
14423
        module.invoke(query);
14424
      }
14425
      else {
14426
        if(instance !== undefined) {
14427
          instance.invoke('destroy');
14428
        }
14429
        module.initialize();
14430
      }
14431
14432
    })
14433
  ;
14434
14435
  return (returnedValue !== undefined)
14436
    ? returnedValue
14437
    : this
14438
  ;
14439
};
14440
14441
$.fn.search.settings = {
14442
14443
  name              : 'Search',
14444
  namespace         : 'search',
14445
14446
  silent            : false,
14447
  debug             : false,
14448
  verbose           : false,
14449
  performance       : true,
14450
14451
  // template to use (specified in settings.templates)
14452
  type              : 'standard',
14453
14454
  // minimum characters required to search
14455
  minCharacters     : 1,
14456
14457
  // whether to select first result after searching automatically
14458
  selectFirstResult : false,
14459
14460
  // API config
14461
  apiSettings       : false,
14462
14463
  // object to search
14464
  source            : false,
14465
14466
  // Whether search should query current term on focus
14467
  searchOnFocus     : true,
14468
14469
  // fields to search
14470
  searchFields   : [
14471
    'title',
14472
    'description'
14473
  ],
14474
14475
  // field to display in standard results template
14476
  displayField   : '',
14477
14478
  // whether to include fuzzy results in local search
14479
  searchFullText : true,
14480
14481
  // whether to add events to prompt automatically
14482
  automatic      : true,
14483
14484
  // delay before hiding menu after blur
14485
  hideDelay      : 0,
14486
14487
  // delay before searching
14488
  searchDelay    : 200,
14489
14490
  // maximum results returned from local
14491
  maxResults     : 7,
14492
14493
  // whether to store lookups in local cache
14494
  cache          : true,
14495
14496
  // whether no results errors should be shown
14497
  showNoResults  : true,
14498
14499
  // transition settings
14500
  transition     : 'scale',
14501
  duration       : 200,
14502
  easing         : 'easeOutExpo',
14503
14504
  // callbacks
14505
  onSelect       : false,
14506
  onResultsAdd   : false,
14507
14508
  onSearchQuery  : function(query){},
0 ignored issues
show
Unused Code introduced by
The parameter query is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
14509
  onResults      : function(response){},
0 ignored issues
show
Unused Code introduced by
The parameter response is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
14510
14511
  onResultsOpen  : function(){},
14512
  onResultsClose : function(){},
14513
14514
  className: {
14515
    animating : 'animating',
14516
    active    : 'active',
14517
    empty     : 'empty',
14518
    focus     : 'focus',
14519
    hidden    : 'hidden',
14520
    loading   : 'loading',
14521
    results   : 'results',
14522
    pressed   : 'down'
14523
  },
14524
14525
  error : {
14526
    source      : 'Cannot search. No source used, and Semantic API module was not included',
14527
    noResults   : 'Your search returned no results',
14528
    logging     : 'Error in debug logging, exiting.',
14529
    noEndpoint  : 'No search endpoint was specified',
14530
    noTemplate  : 'A valid template name was not specified.',
14531
    serverError : 'There was an issue querying the server.',
14532
    maxResults  : 'Results must be an array to use maxResults setting',
14533
    method      : 'The method you called is not defined.'
14534
  },
14535
14536
  metadata: {
14537
    cache   : 'cache',
14538
    results : 'results',
14539
    result  : 'result'
14540
  },
14541
14542
  regExp: {
14543
    escape     : /[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g,
14544
    beginsWith : '(?:\s|^)'
14545
  },
14546
14547
  // maps api response attributes to internal representation
14548
  fields: {
14549
    categories      : 'results',     // array of categories (category view)
14550
    categoryName    : 'name',        // name of category (category view)
14551
    categoryResults : 'results',     // array of results (category view)
14552
    description     : 'description', // result description
14553
    image           : 'image',       // result image
14554
    price           : 'price',       // result price
14555
    results         : 'results',     // array of results (standard)
14556
    title           : 'title',       // result title
14557
    url             : 'url',         // result url
14558
    action          : 'action',      // "view more" object name
14559
    actionText      : 'text',        // "view more" text
14560
    actionURL       : 'url'          // "view more" url
14561
  },
14562
14563
  selector : {
14564
    prompt       : '.prompt',
14565
    searchButton : '.search.button',
14566
    results      : '.results',
14567
    message      : '.results > .message',
14568
    category     : '.category',
14569
    result       : '.result',
14570
    title        : '.title, .name'
14571
  },
14572
14573
  templates: {
14574
    escape: function(string) {
14575
      var
14576
        badChars     = /[&<>"'`]/g,
14577
        shouldEscape = /[&<>"'`]/,
14578
        escape       = {
14579
          "&": "&amp;",
14580
          "<": "&lt;",
14581
          ">": "&gt;",
14582
          '"': "&quot;",
14583
          "'": "&#x27;",
14584
          "`": "&#x60;"
14585
        },
14586
        escapedChar  = function(chr) {
14587
          return escape[chr];
14588
        }
14589
      ;
14590
      if(shouldEscape.test(string)) {
14591
        return string.replace(badChars, escapedChar);
14592
      }
14593
      return string;
14594
    },
14595
    message: function(message, type) {
14596
      var
14597
        html = ''
14598
      ;
14599
      if(message !== undefined && type !== undefined) {
14600
        html +=  ''
14601
          + '<div class="message ' + type + '">'
14602
        ;
14603
        // message type
14604
        if(type == 'empty') {
14605
          html += ''
14606
            + '<div class="header">No Results</div class="header">'
14607
            + '<div class="description">' + message + '</div class="description">'
14608
          ;
14609
        }
14610
        else {
14611
          html += ' <div class="description">' + message + '</div>';
14612
        }
14613
        html += '</div>';
14614
      }
14615
      return html;
14616
    },
14617
    category: function(response, fields) {
14618
      var
14619
        html = '',
14620
        escape = $.fn.search.settings.templates.escape
0 ignored issues
show
Unused Code introduced by
The assignment to variable escape seems to be never used. Consider removing it.
Loading history...
14621
      ;
14622
      if(response[fields.categoryResults] !== undefined) {
14623
14624
        // each category
14625
        $.each(response[fields.categoryResults], function(index, category) {
14626
          if(category[fields.results] !== undefined && category.results.length > 0) {
14627
14628
            html  += '<div class="category">';
14629
14630
            if(category[fields.categoryName] !== undefined) {
14631
              html += '<div class="name">' + category[fields.categoryName] + '</div>';
14632
            }
14633
14634
            // each item inside category
14635
            $.each(category.results, function(index, result) {
14636
              if(result[fields.url]) {
14637
                html  += '<a class="result" href="' + result[fields.url] + '">';
14638
              }
14639
              else {
14640
                html  += '<a class="result">';
14641
              }
14642
              if(result[fields.image] !== undefined) {
14643
                html += ''
14644
                  + '<div class="image">'
14645
                  + ' <img src="' + result[fields.image] + '">'
14646
                  + '</div>'
14647
                ;
14648
              }
14649
              html += '<div class="content">';
14650
              if(result[fields.price] !== undefined) {
14651
                html += '<div class="price">' + result[fields.price] + '</div>';
14652
              }
14653
              if(result[fields.title] !== undefined) {
14654
                html += '<div class="title">' + result[fields.title] + '</div>';
14655
              }
14656
              if(result[fields.description] !== undefined) {
14657
                html += '<div class="description">' + result[fields.description] + '</div>';
14658
              }
14659
              html  += ''
14660
                + '</div>'
14661
              ;
14662
              html += '</a>';
14663
            });
14664
            html  += ''
14665
              + '</div>'
14666
            ;
14667
          }
14668
        });
14669
        if(response[fields.action]) {
14670
          html += ''
14671
          + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">'
14672
          +   response[fields.action][fields.actionText]
14673
          + '</a>';
14674
        }
14675
        return html;
14676
      }
14677
      return false;
14678
    },
14679
    standard: function(response, fields) {
14680
      var
14681
        html = ''
14682
      ;
14683
      if(response[fields.results] !== undefined) {
14684
14685
        // each result
14686
        $.each(response[fields.results], function(index, result) {
14687
          if(result[fields.url]) {
14688
            html  += '<a class="result" href="' + result[fields.url] + '">';
14689
          }
14690
          else {
14691
            html  += '<a class="result">';
14692
          }
14693
          if(result[fields.image] !== undefined) {
14694
            html += ''
14695
              + '<div class="image">'
14696
              + ' <img src="' + result[fields.image] + '">'
14697
              + '</div>'
14698
            ;
14699
          }
14700
          html += '<div class="content">';
14701
          if(result[fields.price] !== undefined) {
14702
            html += '<div class="price">' + result[fields.price] + '</div>';
14703
          }
14704
          if(result[fields.title] !== undefined) {
14705
            html += '<div class="title">' + result[fields.title] + '</div>';
14706
          }
14707
          if(result[fields.description] !== undefined) {
14708
            html += '<div class="description">' + result[fields.description] + '</div>';
14709
          }
14710
          html  += ''
14711
            + '</div>'
14712
          ;
14713
          html += '</a>';
14714
        });
14715
14716
        if(response[fields.action]) {
14717
          html += ''
14718
          + '<a href="' + response[fields.action][fields.actionURL] + '" class="action">'
14719
          +   response[fields.action][fields.actionText]
14720
          + '</a>';
14721
        }
14722
        return html;
14723
      }
14724
      return false;
14725
    }
14726
  }
14727
};
14728
14729
})( jQuery, window, document );
14730
14731
/*!
14732
 * # Semantic UI 2.2.11 - Shape
14733
 * http://github.com/semantic-org/semantic-ui/
14734
 *
14735
 *
14736
 * Released under the MIT license
14737
 * http://opensource.org/licenses/MIT
14738
 *
14739
 */
14740
14741 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
14742
14743
"use strict";
14744
14745
window = (typeof window != 'undefined' && window.Math == Math)
14746
  ? window
14747
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
14748
    ? self
14749
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
14750
;
14751
14752
$.fn.shape = function(parameters) {
14753
  var
14754
    $allModules     = $(this),
14755
    $body           = $('body'),
0 ignored issues
show
Unused Code introduced by
The variable $body seems to be never used. Consider removing it.
Loading history...
14756
14757
    time            = new Date().getTime(),
14758
    performance     = [],
14759
14760
    query           = arguments[0],
14761
    methodInvoked   = (typeof query == 'string'),
14762
    queryArguments  = [].slice.call(arguments, 1),
14763
14764
    requestAnimationFrame = window.requestAnimationFrame
14765
      || window.mozRequestAnimationFrame
14766
      || window.webkitRequestAnimationFrame
14767
      || window.msRequestAnimationFrame
14768
      || function(callback) { setTimeout(callback, 0); },
14769
14770
    returnedValue
14771
  ;
14772
14773
  $allModules
14774
    .each(function() {
14775
      var
14776
        moduleSelector = $allModules.selector || '',
14777
        settings       = ( $.isPlainObject(parameters) )
14778
          ? $.extend(true, {}, $.fn.shape.settings, parameters)
14779
          : $.extend({}, $.fn.shape.settings),
14780
14781
        // internal aliases
14782
        namespace     = settings.namespace,
14783
        selector      = settings.selector,
14784
        error         = settings.error,
14785
        className     = settings.className,
14786
14787
        // define namespaces for modules
14788
        eventNamespace  = '.' + namespace,
14789
        moduleNamespace = 'module-' + namespace,
14790
14791
        // selector cache
14792
        $module       = $(this),
14793
        $sides        = $module.find(selector.sides),
14794
        $side         = $module.find(selector.side),
14795
14796
        // private variables
14797
        nextIndex = false,
14798
        $activeSide,
14799
        $nextSide,
14800
14801
        // standard module
14802
        element       = this,
14803
        instance      = $module.data(moduleNamespace),
14804
        module
14805
      ;
14806
14807
      module = {
14808
14809
        initialize: function() {
14810
          module.verbose('Initializing module for', element);
14811
          module.set.defaultSide();
14812
          module.instantiate();
14813
        },
14814
14815
        instantiate: function() {
14816
          module.verbose('Storing instance of module', module);
14817
          instance = module;
14818
          $module
14819
            .data(moduleNamespace, instance)
14820
          ;
14821
        },
14822
14823
        destroy: function() {
14824
          module.verbose('Destroying previous module for', element);
14825
          $module
14826
            .removeData(moduleNamespace)
14827
            .off(eventNamespace)
14828
          ;
14829
        },
14830
14831
        refresh: function() {
14832
          module.verbose('Refreshing selector cache for', element);
14833
          $module = $(element);
14834
          $sides  = $(this).find(selector.shape);
14835
          $side   = $(this).find(selector.side);
14836
        },
14837
14838
        repaint: function() {
14839
          module.verbose('Forcing repaint event');
14840
          var
14841
            shape          = $sides[0] || document.createElement('div'),
14842
            fakeAssignment = shape.offsetWidth
0 ignored issues
show
Unused Code introduced by
The variable fakeAssignment seems to be never used. Consider removing it.
Loading history...
14843
          ;
14844
        },
14845
14846
        animate: function(propertyObject, callback) {
14847
          module.verbose('Animating box with properties', propertyObject);
14848
          callback = callback || function(event) {
14849
            module.verbose('Executing animation callback');
14850
            if(event !== undefined) {
14851
              event.stopPropagation();
14852
            }
14853
            module.reset();
14854
            module.set.active();
14855
          };
14856
          settings.beforeChange.call($nextSide[0]);
14857
          if(module.get.transitionEvent()) {
14858
            module.verbose('Starting CSS animation');
14859
            $module
14860
              .addClass(className.animating)
14861
            ;
14862
            $sides
14863
              .css(propertyObject)
14864
              .one(module.get.transitionEvent(), callback)
14865
            ;
14866
            module.set.duration(settings.duration);
14867
            requestAnimationFrame(function() {
14868
              $module
14869
                .addClass(className.animating)
14870
              ;
14871
              $activeSide
14872
                .addClass(className.hidden)
14873
              ;
14874
            });
14875
          }
14876
          else {
14877
            callback();
14878
          }
14879
        },
14880
14881
        queue: function(method) {
14882
          module.debug('Queueing animation of', method);
14883
          $sides
14884
            .one(module.get.transitionEvent(), function() {
14885
              module.debug('Executing queued animation');
14886
              setTimeout(function(){
14887
                $module.shape(method);
14888
              }, 0);
14889
            })
14890
          ;
14891
        },
14892
14893
        reset: function() {
14894
          module.verbose('Animating states reset');
14895
          $module
14896
            .removeClass(className.animating)
14897
            .attr('style', '')
14898
            .removeAttr('style')
14899
          ;
14900
          // removeAttr style does not consistently work in safari
14901
          $sides
14902
            .attr('style', '')
14903
            .removeAttr('style')
14904
          ;
14905
          $side
14906
            .attr('style', '')
14907
            .removeAttr('style')
14908
            .removeClass(className.hidden)
14909
          ;
14910
          $nextSide
14911
            .removeClass(className.animating)
14912
            .attr('style', '')
14913
            .removeAttr('style')
14914
          ;
14915
        },
14916
14917
        is: {
14918
          complete: function() {
14919
            return ($side.filter('.' + className.active)[0] == $nextSide[0]);
14920
          },
14921
          animating: function() {
14922
            return $module.hasClass(className.animating);
14923
          }
14924
        },
14925
14926
        set: {
14927
14928
          defaultSide: function() {
14929
            $activeSide = $module.find('.' + settings.className.active);
14930
            $nextSide   = ( $activeSide.next(selector.side).length > 0 )
14931
              ? $activeSide.next(selector.side)
14932
              : $module.find(selector.side).first()
14933
            ;
14934
            nextIndex = false;
14935
            module.verbose('Active side set to', $activeSide);
14936
            module.verbose('Next side set to', $nextSide);
14937
          },
14938
14939
          duration: function(duration) {
14940
            duration = duration || settings.duration;
14941
            duration = (typeof duration == 'number')
14942
              ? duration + 'ms'
14943
              : duration
14944
            ;
14945
            module.verbose('Setting animation duration', duration);
14946
            if(settings.duration || settings.duration === 0) {
14947
              $sides.add($side)
14948
                .css({
14949
                  '-webkit-transition-duration': duration,
14950
                  '-moz-transition-duration': duration,
14951
                  '-ms-transition-duration': duration,
14952
                  '-o-transition-duration': duration,
14953
                  'transition-duration': duration
14954
                })
14955
              ;
14956
            }
14957
          },
14958
14959
          currentStageSize: function() {
14960
            var
14961
              $activeSide = $module.find('.' + settings.className.active),
14962
              width       = $activeSide.outerWidth(true),
14963
              height      = $activeSide.outerHeight(true)
14964
            ;
14965
            $module
14966
              .css({
14967
                width: width,
14968
                height: height
14969
              })
14970
            ;
14971
          },
14972
14973
          stageSize: function() {
14974
            var
14975
              $clone      = $module.clone().addClass(className.loading),
14976
              $activeSide = $clone.find('.' + settings.className.active),
14977
              $nextSide   = (nextIndex)
14978
                ? $clone.find(selector.side).eq(nextIndex)
14979
                : ( $activeSide.next(selector.side).length > 0 )
14980
                  ? $activeSide.next(selector.side)
14981
                  : $clone.find(selector.side).first(),
14982
              newWidth    = (settings.width == 'next')
14983
                ? $nextSide.outerWidth(true)
14984
                : (settings.width == 'initial')
14985
                  ? $module.width()
14986
                  : settings.width,
14987
              newHeight    = (settings.height == 'next')
14988
                ? $nextSide.outerHeight(true)
14989
                : (settings.height == 'initial')
14990
                  ? $module.height()
14991
                  : settings.height
14992
            ;
14993
            $activeSide.removeClass(className.active);
14994
            $nextSide.addClass(className.active);
14995
            $clone.insertAfter($module);
14996
            $clone.remove();
14997
            if(settings.width != 'auto') {
14998
              $module.css('width', newWidth + settings.jitter);
14999
              module.verbose('Specifying width during animation', newWidth);
15000
            }
15001
            if(settings.height != 'auto') {
15002
              $module.css('height', newHeight + settings.jitter);
15003
              module.verbose('Specifying height during animation', newHeight);
15004
            }
15005
          },
15006
15007
          nextSide: function(selector) {
15008
            nextIndex = selector;
15009
            $nextSide = $side.filter(selector);
15010
            nextIndex = $side.index($nextSide);
15011
            if($nextSide.length === 0) {
15012
              module.set.defaultSide();
15013
              module.error(error.side);
15014
            }
15015
            module.verbose('Next side manually set to', $nextSide);
15016
          },
15017
15018
          active: function() {
15019
            module.verbose('Setting new side to active', $nextSide);
15020
            $side
15021
              .removeClass(className.active)
15022
            ;
15023
            $nextSide
15024
              .addClass(className.active)
15025
            ;
15026
            settings.onChange.call($nextSide[0]);
15027
            module.set.defaultSide();
15028
          }
15029
        },
15030
15031
        flip: {
15032
15033
          up: function() {
15034
            if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
15035
              module.debug('Side already visible', $nextSide);
15036
              return;
15037
            }
15038
            if( !module.is.animating()) {
15039
              module.debug('Flipping up', $nextSide);
15040
              var
15041
                transform = module.get.transform.up()
15042
              ;
15043
              module.set.stageSize();
15044
              module.stage.above();
15045
              module.animate(transform);
15046
            }
15047
            else {
15048
              module.queue('flip up');
15049
            }
15050
          },
15051
15052
          down: function() {
15053
            if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
15054
              module.debug('Side already visible', $nextSide);
15055
              return;
15056
            }
15057
            if( !module.is.animating()) {
15058
              module.debug('Flipping down', $nextSide);
15059
              var
15060
                transform = module.get.transform.down()
15061
              ;
15062
              module.set.stageSize();
15063
              module.stage.below();
15064
              module.animate(transform);
15065
            }
15066
            else {
15067
              module.queue('flip down');
15068
            }
15069
          },
15070
15071
          left: function() {
15072
            if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
15073
              module.debug('Side already visible', $nextSide);
15074
              return;
15075
            }
15076
            if( !module.is.animating()) {
15077
              module.debug('Flipping left', $nextSide);
15078
              var
15079
                transform = module.get.transform.left()
15080
              ;
15081
              module.set.stageSize();
15082
              module.stage.left();
15083
              module.animate(transform);
15084
            }
15085
            else {
15086
              module.queue('flip left');
15087
            }
15088
          },
15089
15090
          right: function() {
15091
            if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
15092
              module.debug('Side already visible', $nextSide);
15093
              return;
15094
            }
15095
            if( !module.is.animating()) {
15096
              module.debug('Flipping right', $nextSide);
15097
              var
15098
                transform = module.get.transform.right()
15099
              ;
15100
              module.set.stageSize();
15101
              module.stage.right();
15102
              module.animate(transform);
15103
            }
15104
            else {
15105
              module.queue('flip right');
15106
            }
15107
          },
15108
15109
          over: function() {
15110
            if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
15111
              module.debug('Side already visible', $nextSide);
15112
              return;
15113
            }
15114
            if( !module.is.animating()) {
15115
              module.debug('Flipping over', $nextSide);
15116
              module.set.stageSize();
15117
              module.stage.behind();
15118
              module.animate(module.get.transform.over() );
15119
            }
15120
            else {
15121
              module.queue('flip over');
15122
            }
15123
          },
15124
15125
          back: function() {
15126
            if(module.is.complete() && !module.is.animating() && !settings.allowRepeats) {
15127
              module.debug('Side already visible', $nextSide);
15128
              return;
15129
            }
15130
            if( !module.is.animating()) {
15131
              module.debug('Flipping back', $nextSide);
15132
              module.set.stageSize();
15133
              module.stage.behind();
15134
              module.animate(module.get.transform.back() );
15135
            }
15136
            else {
15137
              module.queue('flip back');
15138
            }
15139
          }
15140
15141
        },
15142
15143
        get: {
15144
15145
          transform: {
15146
            up: function() {
15147
              var
15148
                translate = {
15149
                  y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
15150
                  z: -($activeSide.outerHeight(true) / 2)
15151
                }
15152
              ;
15153
              return {
15154
                transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(-90deg)'
15155
              };
15156
            },
15157
15158
            down: function() {
15159
              var
15160
                translate = {
15161
                  y: -(($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
15162
                  z: -($activeSide.outerHeight(true) / 2)
15163
                }
15164
              ;
15165
              return {
15166
                transform: 'translateY(' + translate.y + 'px) translateZ('+ translate.z + 'px) rotateX(90deg)'
15167
              };
15168
            },
15169
15170
            left: function() {
15171
              var
15172
                translate = {
15173
                  x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2),
15174
                  z : -($activeSide.outerWidth(true) / 2)
15175
                }
15176
              ;
15177
              return {
15178
                transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(90deg)'
15179
              };
15180
            },
15181
15182
            right: function() {
15183
              var
15184
                translate = {
15185
                  x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2),
15186
                  z : -($activeSide.outerWidth(true) / 2)
15187
                }
15188
              ;
15189
              return {
15190
                transform: 'translateX(' + translate.x + 'px) translateZ(' + translate.z + 'px) rotateY(-90deg)'
15191
              };
15192
            },
15193
15194
            over: function() {
15195
              var
15196
                translate = {
15197
                  x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2)
15198
                }
15199
              ;
15200
              return {
15201
                transform: 'translateX(' + translate.x + 'px) rotateY(180deg)'
15202
              };
15203
            },
15204
15205
            back: function() {
15206
              var
15207
                translate = {
15208
                  x : -(($activeSide.outerWidth(true) - $nextSide.outerWidth(true)) / 2)
15209
                }
15210
              ;
15211
              return {
15212
                transform: 'translateX(' + translate.x + 'px) rotateY(-180deg)'
15213
              };
15214
            }
15215
          },
15216
15217
          transitionEvent: function() {
15218
            var
15219
              element     = document.createElement('element'),
15220
              transitions = {
15221
                'transition'       :'transitionend',
15222
                'OTransition'      :'oTransitionEnd',
15223
                'MozTransition'    :'transitionend',
15224
                'WebkitTransition' :'webkitTransitionEnd'
15225
              },
15226
              transition
15227
            ;
15228
            for(transition in transitions){
15229
              if( element.style[transition] !== undefined ){
15230
                return transitions[transition];
15231
              }
15232
            }
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
15233
          },
15234
15235
          nextSide: function() {
15236
            return ( $activeSide.next(selector.side).length > 0 )
15237
              ? $activeSide.next(selector.side)
15238
              : $module.find(selector.side).first()
15239
            ;
15240
          }
15241
15242
        },
15243
15244
        stage: {
15245
15246
          above: function() {
15247
            var
15248
              box = {
15249
                origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
15250
                depth  : {
15251
                  active : ($nextSide.outerHeight(true) / 2),
15252
                  next   : ($activeSide.outerHeight(true) / 2)
15253
                }
15254
              }
15255
            ;
15256
            module.verbose('Setting the initial animation position as above', $nextSide, box);
15257
            $sides
15258
              .css({
15259
                'transform' : 'translateZ(-' + box.depth.active + 'px)'
15260
              })
15261
            ;
15262
            $activeSide
15263
              .css({
15264
                'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
15265
              })
15266
            ;
15267
            $nextSide
15268
              .addClass(className.animating)
15269
              .css({
15270
                'top'       : box.origin + 'px',
15271
                'transform' : 'rotateX(90deg) translateZ(' + box.depth.next + 'px)'
15272
              })
15273
            ;
15274
          },
15275
15276
          below: function() {
15277
            var
15278
              box = {
15279
                origin : (($activeSide.outerHeight(true) - $nextSide.outerHeight(true)) / 2),
15280
                depth  : {
15281
                  active : ($nextSide.outerHeight(true) / 2),
15282
                  next   : ($activeSide.outerHeight(true) / 2)
15283
                }
15284
              }
15285
            ;
15286
            module.verbose('Setting the initial animation position as below', $nextSide, box);
15287
            $sides
15288
              .css({
15289
                'transform' : 'translateZ(-' + box.depth.active + 'px)'
15290
              })
15291
            ;
15292
            $activeSide
15293
              .css({
15294
                'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
15295
              })
15296
            ;
15297
            $nextSide
15298
              .addClass(className.animating)
15299
              .css({
15300
                'top'       : box.origin + 'px',
15301
                'transform' : 'rotateX(-90deg) translateZ(' + box.depth.next + 'px)'
15302
              })
15303
            ;
15304
          },
15305
15306
          left: function() {
15307
            var
15308
              height = {
15309
                active : $activeSide.outerWidth(true),
15310
                next   : $nextSide.outerWidth(true)
15311
              },
15312
              box = {
15313
                origin : ( ( height.active - height.next ) / 2),
15314
                depth  : {
15315
                  active : (height.next / 2),
15316
                  next   : (height.active / 2)
15317
                }
15318
              }
15319
            ;
15320
            module.verbose('Setting the initial animation position as left', $nextSide, box);
15321
            $sides
15322
              .css({
15323
                'transform' : 'translateZ(-' + box.depth.active + 'px)'
15324
              })
15325
            ;
15326
            $activeSide
15327
              .css({
15328
                'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
15329
              })
15330
            ;
15331
            $nextSide
15332
              .addClass(className.animating)
15333
              .css({
15334
                'left'      : box.origin + 'px',
15335
                'transform' : 'rotateY(-90deg) translateZ(' + box.depth.next + 'px)'
15336
              })
15337
            ;
15338
          },
15339
15340
          right: function() {
15341
            var
15342
              height = {
15343
                active : $activeSide.outerWidth(true),
15344
                next   : $nextSide.outerWidth(true)
15345
              },
15346
              box = {
15347
                origin : ( ( height.active - height.next ) / 2),
15348
                depth  : {
15349
                  active : (height.next / 2),
15350
                  next   : (height.active / 2)
15351
                }
15352
              }
15353
            ;
15354
            module.verbose('Setting the initial animation position as left', $nextSide, box);
15355
            $sides
15356
              .css({
15357
                'transform' : 'translateZ(-' + box.depth.active + 'px)'
15358
              })
15359
            ;
15360
            $activeSide
15361
              .css({
15362
                'transform' : 'rotateY(0deg) translateZ(' + box.depth.active + 'px)'
15363
              })
15364
            ;
15365
            $nextSide
15366
              .addClass(className.animating)
15367
              .css({
15368
                'left'      : box.origin + 'px',
15369
                'transform' : 'rotateY(90deg) translateZ(' + box.depth.next + 'px)'
15370
              })
15371
            ;
15372
          },
15373
15374
          behind: function() {
15375
            var
15376
              height = {
15377
                active : $activeSide.outerWidth(true),
15378
                next   : $nextSide.outerWidth(true)
15379
              },
15380
              box = {
15381
                origin : ( ( height.active - height.next ) / 2),
15382
                depth  : {
15383
                  active : (height.next / 2),
15384
                  next   : (height.active / 2)
15385
                }
15386
              }
15387
            ;
15388
            module.verbose('Setting the initial animation position as behind', $nextSide, box);
15389
            $activeSide
15390
              .css({
15391
                'transform' : 'rotateY(0deg)'
15392
              })
15393
            ;
15394
            $nextSide
15395
              .addClass(className.animating)
15396
              .css({
15397
                'left'      : box.origin + 'px',
15398
                'transform' : 'rotateY(-180deg)'
15399
              })
15400
            ;
15401
          }
15402
        },
15403
        setting: function(name, value) {
15404
          module.debug('Changing setting', name, value);
15405
          if( $.isPlainObject(name) ) {
15406
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
15407
          }
15408
          else if(value !== undefined) {
15409
            if($.isPlainObject(settings[name])) {
15410
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
15411
            }
15412
            else {
15413
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
15414
            }
15415
          }
15416
          else {
15417
            return settings[name];
15418
          }
15419
        },
15420
        internal: function(name, value) {
15421
          if( $.isPlainObject(name) ) {
15422
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
15423
          }
15424
          else if(value !== undefined) {
15425
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
15426
          }
15427
          else {
15428
            return module[name];
15429
          }
15430
        },
15431
        debug: function() {
15432
          if(!settings.silent && settings.debug) {
15433
            if(settings.performance) {
15434
              module.performance.log(arguments);
15435
            }
15436
            else {
15437
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
15438
              module.debug.apply(console, arguments);
15439
            }
15440
          }
15441
        },
15442
        verbose: function() {
15443
          if(!settings.silent && settings.verbose && settings.debug) {
15444
            if(settings.performance) {
15445
              module.performance.log(arguments);
15446
            }
15447
            else {
15448
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
15449
              module.verbose.apply(console, arguments);
15450
            }
15451
          }
15452
        },
15453
        error: function() {
15454
          if(!settings.silent) {
15455
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
15456
            module.error.apply(console, arguments);
15457
          }
15458
        },
15459
        performance: {
15460
          log: function(message) {
15461
            var
15462
              currentTime,
15463
              executionTime,
15464
              previousTime
15465
            ;
15466
            if(settings.performance) {
15467
              currentTime   = new Date().getTime();
15468
              previousTime  = time || currentTime;
15469
              executionTime = currentTime - previousTime;
15470
              time          = currentTime;
15471
              performance.push({
15472
                'Name'           : message[0],
15473
                'Arguments'      : [].slice.call(message, 1) || '',
15474
                'Element'        : element,
15475
                'Execution Time' : executionTime
15476
              });
15477
            }
15478
            clearTimeout(module.performance.timer);
15479
            module.performance.timer = setTimeout(module.performance.display, 500);
15480
          },
15481
          display: function() {
15482
            var
15483
              title = settings.name + ':',
15484
              totalTime = 0
15485
            ;
15486
            time = false;
15487
            clearTimeout(module.performance.timer);
15488
            $.each(performance, function(index, data) {
15489
              totalTime += data['Execution Time'];
15490
            });
15491
            title += ' ' + totalTime + 'ms';
15492
            if(moduleSelector) {
15493
              title += ' \'' + moduleSelector + '\'';
15494
            }
15495
            if($allModules.length > 1) {
15496
              title += ' ' + '(' + $allModules.length + ')';
15497
            }
15498
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
15499
              console.groupCollapsed(title);
15500
              if(console.table) {
15501
                console.table(performance);
15502
              }
15503
              else {
15504
                $.each(performance, function(index, data) {
15505
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
15506
                });
15507
              }
15508
              console.groupEnd();
15509
            }
15510
            performance = [];
15511
          }
15512
        },
15513
        invoke: function(query, passedArguments, context) {
15514
          var
15515
            object = instance,
15516
            maxDepth,
15517
            found,
15518
            response
15519
          ;
15520
          passedArguments = passedArguments || queryArguments;
15521
          context         = element         || context;
15522
          if(typeof query == 'string' && object !== undefined) {
15523
            query    = query.split(/[\. ]/);
15524
            maxDepth = query.length - 1;
15525
            $.each(query, function(depth, value) {
15526
              var camelCaseValue = (depth != maxDepth)
15527
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
15528
                : query
15529
              ;
15530
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
15531
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
15532
              }
15533
              else if( object[camelCaseValue] !== undefined ) {
15534
                found = object[camelCaseValue];
15535
                return false;
15536
              }
15537
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
15538
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
15539
              }
15540
              else if( object[value] !== undefined ) {
15541
                found = object[value];
15542
                return false;
15543
              }
15544
              else {
15545
                return false;
15546
              }
15547
            });
15548
          }
15549
          if ( $.isFunction( found ) ) {
15550
            response = found.apply(context, passedArguments);
15551
          }
15552
          else if(found !== undefined) {
15553
            response = found;
15554
          }
15555
          if($.isArray(returnedValue)) {
15556
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 15552 is false. Are you sure the function push handles undefined variables?
Loading history...
15557
          }
15558
          else if(returnedValue !== undefined) {
15559
            returnedValue = [returnedValue, response];
15560
          }
15561
          else if(response !== undefined) {
15562
            returnedValue = response;
15563
          }
15564
          return found;
15565
        }
15566
      };
15567
15568
      if(methodInvoked) {
15569
        if(instance === undefined) {
15570
          module.initialize();
15571
        }
15572
        module.invoke(query);
15573
      }
15574
      else {
15575
        if(instance !== undefined) {
15576
          instance.invoke('destroy');
15577
        }
15578
        module.initialize();
15579
      }
15580
    })
15581
  ;
15582
15583
  return (returnedValue !== undefined)
15584
    ? returnedValue
15585
    : this
15586
  ;
15587
};
15588
15589
$.fn.shape.settings = {
15590
15591
  // module info
15592
  name : 'Shape',
15593
15594
  // hide all debug content
15595
  silent     : false,
15596
15597
  // debug content outputted to console
15598
  debug      : false,
15599
15600
  // verbose debug output
15601
  verbose    : false,
15602
15603
  // fudge factor in pixels when swapping from 2d to 3d (can be useful to correct rounding errors)
15604
  jitter     : 0,
15605
15606
  // performance data output
15607
  performance: true,
15608
15609
  // event namespace
15610
  namespace  : 'shape',
15611
15612
  // width during animation, can be set to 'auto', initial', 'next' or pixel amount
15613
  width: 'initial',
15614
15615
  // height during animation, can be set to 'auto', 'initial', 'next' or pixel amount
15616
  height: 'initial',
15617
15618
  // callback occurs on side change
15619
  beforeChange : function() {},
15620
  onChange     : function() {},
15621
15622
  // allow animation to same side
15623
  allowRepeats: false,
15624
15625
  // animation duration
15626
  duration   : false,
15627
15628
  // possible errors
15629
  error: {
15630
    side   : 'You tried to switch to a side that does not exist.',
15631
    method : 'The method you called is not defined'
15632
  },
15633
15634
  // classnames used
15635
  className   : {
15636
    animating : 'animating',
15637
    hidden    : 'hidden',
15638
    loading   : 'loading',
15639
    active    : 'active'
15640
  },
15641
15642
  // selectors used
15643
  selector    : {
15644
    sides : '.sides',
15645
    side  : '.side'
15646
  }
15647
15648
};
15649
15650
15651
})( jQuery, window, document );
15652
15653
/*!
15654
 * # Semantic UI 2.2.11 - Sidebar
15655
 * http://github.com/semantic-org/semantic-ui/
15656
 *
15657
 *
15658
 * Released under the MIT license
15659
 * http://opensource.org/licenses/MIT
15660
 *
15661
 */
15662
15663 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
15664
15665
"use strict";
15666
15667
window = (typeof window != 'undefined' && window.Math == Math)
15668
  ? window
15669
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
15670
    ? self
15671
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
15672
;
15673
15674
$.fn.sidebar = function(parameters) {
15675
  var
15676
    $allModules     = $(this),
15677
    $window         = $(window),
15678
    $document       = $(document),
15679
    $html           = $('html'),
15680
    $head           = $('head'),
15681
15682
    moduleSelector  = $allModules.selector || '',
15683
15684
    time            = new Date().getTime(),
15685
    performance     = [],
15686
15687
    query           = arguments[0],
15688
    methodInvoked   = (typeof query == 'string'),
15689
    queryArguments  = [].slice.call(arguments, 1),
15690
15691
    requestAnimationFrame = window.requestAnimationFrame
15692
      || window.mozRequestAnimationFrame
15693
      || window.webkitRequestAnimationFrame
15694
      || window.msRequestAnimationFrame
15695
      || function(callback) { setTimeout(callback, 0); },
15696
15697
    returnedValue
15698
  ;
15699
15700
  $allModules
15701
    .each(function() {
15702
      var
15703
        settings        = ( $.isPlainObject(parameters) )
15704
          ? $.extend(true, {}, $.fn.sidebar.settings, parameters)
15705
          : $.extend({}, $.fn.sidebar.settings),
15706
15707
        selector        = settings.selector,
15708
        className       = settings.className,
15709
        namespace       = settings.namespace,
15710
        regExp          = settings.regExp,
15711
        error           = settings.error,
15712
15713
        eventNamespace  = '.' + namespace,
15714
        moduleNamespace = 'module-' + namespace,
15715
15716
        $module         = $(this),
15717
        $context        = $(settings.context),
15718
15719
        $sidebars       = $module.children(selector.sidebar),
15720
        $fixed          = $context.children(selector.fixed),
0 ignored issues
show
Unused Code introduced by
The variable $fixed seems to be never used. Consider removing it.
Loading history...
15721
        $pusher         = $context.children(selector.pusher),
15722
        $style,
15723
15724
        element         = this,
15725
        instance        = $module.data(moduleNamespace),
15726
15727
        elementNamespace,
15728
        id,
15729
        currentScroll,
15730
        transitionEvent,
15731
15732
        module
15733
      ;
15734
15735
      module      = {
15736
15737
        initialize: function() {
15738
          module.debug('Initializing sidebar', parameters);
15739
15740
          module.create.id();
15741
15742
          transitionEvent = module.get.transitionEvent();
15743
15744
          // avoids locking rendering if initialized in onReady
15745
          if(settings.delaySetup) {
15746
            requestAnimationFrame(module.setup.layout);
15747
          }
15748
          else {
15749
            module.setup.layout();
15750
          }
15751
15752
          requestAnimationFrame(function() {
15753
            module.setup.cache();
15754
          });
15755
15756
          module.instantiate();
15757
        },
15758
15759
        instantiate: function() {
15760
          module.verbose('Storing instance of module', module);
15761
          instance = module;
15762
          $module
15763
            .data(moduleNamespace, module)
15764
          ;
15765
        },
15766
15767
        create: {
15768
          id: function() {
15769
            id = (Math.random().toString(16) + '000000000').substr(2,8);
15770
            elementNamespace = '.' + id;
15771
            module.verbose('Creating unique id for element', id);
15772
          }
15773
        },
15774
15775
        destroy: function() {
15776
          module.verbose('Destroying previous module for', $module);
15777
          $module
15778
            .off(eventNamespace)
15779
            .removeData(moduleNamespace)
15780
          ;
15781
          if(module.is.ios()) {
15782
            module.remove.ios();
15783
          }
15784
          // bound by uuid
15785
          $context.off(elementNamespace);
15786
          $window.off(elementNamespace);
15787
          $document.off(elementNamespace);
15788
        },
15789
15790
        event: {
15791
          clickaway: function(event) {
15792
            var
15793
              clickedInPusher = ($pusher.find(event.target).length > 0 || $pusher.is(event.target)),
15794
              clickedContext  = ($context.is(event.target))
15795
            ;
15796
            if(clickedInPusher) {
15797
              module.verbose('User clicked on dimmed page');
15798
              module.hide();
15799
            }
15800
            if(clickedContext) {
15801
              module.verbose('User clicked on dimmable context (scaled out page)');
15802
              module.hide();
15803
            }
15804
          },
15805
          touch: function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
15806
            //event.stopPropagation();
15807
          },
15808
          containScroll: function(event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
15809
            if(element.scrollTop <= 0)  {
15810
              element.scrollTop = 1;
15811
            }
15812
            if((element.scrollTop + element.offsetHeight) >= element.scrollHeight) {
15813
              element.scrollTop = element.scrollHeight - element.offsetHeight - 1;
15814
            }
15815
          },
15816
          scroll: function(event) {
15817
            if( $(event.target).closest(selector.sidebar).length === 0 ) {
15818
              event.preventDefault();
15819
            }
15820
          }
15821
        },
15822
15823
        bind: {
15824
          clickaway: function() {
15825
            module.verbose('Adding clickaway events to context', $context);
15826
            if(settings.closable) {
15827
              $context
15828
                .on('click'    + elementNamespace, module.event.clickaway)
15829
                .on('touchend' + elementNamespace, module.event.clickaway)
15830
              ;
15831
            }
15832
          },
15833
          scrollLock: function() {
15834
            if(settings.scrollLock) {
15835
              module.debug('Disabling page scroll');
15836
              $window
15837
                .on('DOMMouseScroll' + elementNamespace, module.event.scroll)
15838
              ;
15839
            }
15840
            module.verbose('Adding events to contain sidebar scroll');
15841
            $document
15842
              .on('touchmove' + elementNamespace, module.event.touch)
15843
            ;
15844
            $module
15845
              .on('scroll' + eventNamespace, module.event.containScroll)
15846
            ;
15847
          }
15848
        },
15849
        unbind: {
15850
          clickaway: function() {
15851
            module.verbose('Removing clickaway events from context', $context);
15852
            $context.off(elementNamespace);
15853
          },
15854
          scrollLock: function() {
15855
            module.verbose('Removing scroll lock from page');
15856
            $document.off(elementNamespace);
15857
            $window.off(elementNamespace);
15858
            $module.off('scroll' + eventNamespace);
15859
          }
15860
        },
15861
15862
        add: {
15863
          inlineCSS: function() {
15864
            var
15865
              width     = module.cache.width  || $module.outerWidth(),
15866
              height    = module.cache.height || $module.outerHeight(),
15867
              isRTL     = module.is.rtl(),
15868
              direction = module.get.direction(),
15869
              distance  = {
15870
                left   : width,
15871
                right  : -width,
15872
                top    : height,
15873
                bottom : -height
15874
              },
15875
              style
15876
            ;
15877
15878
            if(isRTL){
15879
              module.verbose('RTL detected, flipping widths');
15880
              distance.left = -width;
15881
              distance.right = width;
15882
            }
15883
15884
            style  = '<style>';
15885
15886
            if(direction === 'left' || direction === 'right') {
15887
              module.debug('Adding CSS rules for animation distance', width);
15888
              style  += ''
15889
                + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
15890
                + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
15891
                + '   -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
15892
                + '           transform: translate3d('+ distance[direction] + 'px, 0, 0);'
15893
                + ' }'
15894
              ;
15895
            }
15896
            else if(direction === 'top' || direction == 'bottom') {
15897
              style  += ''
15898
                + ' .ui.visible.' + direction + '.sidebar ~ .fixed,'
15899
                + ' .ui.visible.' + direction + '.sidebar ~ .pusher {'
15900
                + '   -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
15901
                + '           transform: translate3d(0, ' + distance[direction] + 'px, 0);'
15902
                + ' }'
15903
              ;
15904
            }
15905
15906
            /* IE is only browser not to create context with transforms */
15907
            /* https://www.w3.org/Bugs/Public/show_bug.cgi?id=16328 */
15908
            if( module.is.ie() ) {
15909
              if(direction === 'left' || direction === 'right') {
15910
                module.debug('Adding CSS rules for animation distance', width);
15911
                style  += ''
15912
                  + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
15913
                  + '   -webkit-transform: translate3d('+ distance[direction] + 'px, 0, 0);'
15914
                  + '           transform: translate3d('+ distance[direction] + 'px, 0, 0);'
15915
                  + ' }'
15916
                ;
15917
              }
15918
              else if(direction === 'top' || direction == 'bottom') {
15919
                style  += ''
15920
                  + ' body.pushable > .ui.visible.' + direction + '.sidebar ~ .pusher:after {'
15921
                  + '   -webkit-transform: translate3d(0, ' + distance[direction] + 'px, 0);'
15922
                  + '           transform: translate3d(0, ' + distance[direction] + 'px, 0);'
15923
                  + ' }'
15924
                ;
15925
              }
15926
              /* opposite sides visible forces content overlay */
15927
              style += ''
15928
                + ' body.pushable > .ui.visible.left.sidebar ~ .ui.visible.right.sidebar ~ .pusher:after,'
15929
                + ' body.pushable > .ui.visible.right.sidebar ~ .ui.visible.left.sidebar ~ .pusher:after {'
15930
                + '   -webkit-transform: translate3d(0px, 0, 0);'
15931
                + '           transform: translate3d(0px, 0, 0);'
15932
                + ' }'
15933
              ;
15934
            }
15935
            style += '</style>';
15936
            $style = $(style)
15937
              .appendTo($head)
15938
            ;
15939
            module.debug('Adding sizing css to head', $style);
15940
          }
15941
        },
15942
15943
        refresh: function() {
15944
          module.verbose('Refreshing selector cache');
15945
          $context  = $(settings.context);
15946
          $sidebars = $context.children(selector.sidebar);
15947
          $pusher   = $context.children(selector.pusher);
15948
          $fixed    = $context.children(selector.fixed);
0 ignored issues
show
Unused Code introduced by
The variable $fixed seems to be never used. Consider removing it.
Loading history...
15949
          module.clear.cache();
15950
        },
15951
15952
        refreshSidebars: function() {
15953
          module.verbose('Refreshing other sidebars');
15954
          $sidebars = $context.children(selector.sidebar);
15955
        },
15956
15957
        repaint: function() {
15958
          module.verbose('Forcing repaint event');
15959
          element.style.display = 'none';
15960
          var ignored = element.offsetHeight;
0 ignored issues
show
Unused Code introduced by
The variable ignored seems to be never used. Consider removing it.
Loading history...
15961
          element.scrollTop = element.scrollTop;
15962
          element.style.display = '';
15963
        },
15964
15965
        setup: {
15966
          cache: function() {
15967
            module.cache = {
15968
              width  : $module.outerWidth(),
15969
              height : $module.outerHeight(),
15970
              rtl    : ($module.css('direction') == 'rtl')
15971
            };
15972
          },
15973
          layout: function() {
15974
            if( $context.children(selector.pusher).length === 0 ) {
15975
              module.debug('Adding wrapper element for sidebar');
15976
              module.error(error.pusher);
15977
              $pusher = $('<div class="pusher" />');
15978
              $context
15979
                .children()
15980
                  .not(selector.omitted)
15981
                  .not($sidebars)
15982
                  .wrapAll($pusher)
15983
              ;
15984
              module.refresh();
15985
            }
15986
            if($module.nextAll(selector.pusher).length === 0 || $module.nextAll(selector.pusher)[0] !== $pusher[0]) {
15987
              module.debug('Moved sidebar to correct parent element');
15988
              module.error(error.movedSidebar, element);
15989
              $module.detach().prependTo($context);
15990
              module.refresh();
15991
            }
15992
            module.clear.cache();
15993
            module.set.pushable();
15994
            module.set.direction();
15995
          }
15996
        },
15997
15998
        attachEvents: function(selector, event) {
15999
          var
16000
            $toggle = $(selector)
16001
          ;
16002
          event = $.isFunction(module[event])
16003
            ? module[event]
16004
            : module.toggle
16005
          ;
16006
          if($toggle.length > 0) {
16007
            module.debug('Attaching sidebar events to element', selector, event);
16008
            $toggle
16009
              .on('click' + eventNamespace, event)
16010
            ;
16011
          }
16012
          else {
16013
            module.error(error.notFound, selector);
16014
          }
16015
        },
16016
16017
        show: function(callback) {
16018
          callback = $.isFunction(callback)
16019
            ? callback
16020
            : function(){}
16021
          ;
16022
          if(module.is.hidden()) {
16023
            module.refreshSidebars();
16024
            if(settings.overlay)  {
16025
              module.error(error.overlay);
16026
              settings.transition = 'overlay';
16027
            }
16028
            module.refresh();
16029
            if(module.othersActive()) {
16030
              module.debug('Other sidebars currently visible');
16031
              if(settings.exclusive) {
16032
                // if not overlay queue animation after hide
16033
                if(settings.transition != 'overlay') {
16034
                  module.hideOthers(module.show);
16035
                  return;
16036
                }
16037
                else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
16038
                  module.hideOthers();
16039
                }
16040
              }
16041
              else {
16042
                settings.transition = 'overlay';
16043
              }
16044
            }
16045
            module.pushPage(function() {
16046
              callback.call(element);
16047
              settings.onShow.call(element);
16048
            });
16049
            settings.onChange.call(element);
16050
            settings.onVisible.call(element);
16051
          }
16052
          else {
16053
            module.debug('Sidebar is already visible');
16054
          }
16055
        },
16056
16057
        hide: function(callback) {
16058
          callback = $.isFunction(callback)
16059
            ? callback
16060
            : function(){}
16061
          ;
16062
          if(module.is.visible() || module.is.animating()) {
16063
            module.debug('Hiding sidebar', callback);
16064
            module.refreshSidebars();
16065
            module.pullPage(function() {
16066
              callback.call(element);
16067
              settings.onHidden.call(element);
16068
            });
16069
            settings.onChange.call(element);
16070
            settings.onHide.call(element);
16071
          }
16072
        },
16073
16074
        othersAnimating: function() {
16075
          return ($sidebars.not($module).filter('.' + className.animating).length > 0);
16076
        },
16077
        othersVisible: function() {
16078
          return ($sidebars.not($module).filter('.' + className.visible).length > 0);
16079
        },
16080
        othersActive: function() {
16081
          return(module.othersVisible() || module.othersAnimating());
16082
        },
16083
16084
        hideOthers: function(callback) {
16085
          var
16086
            $otherSidebars = $sidebars.not($module).filter('.' + className.visible),
16087
            sidebarCount   = $otherSidebars.length,
16088
            callbackCount  = 0
16089
          ;
16090
          callback = callback || function(){};
16091
          $otherSidebars
16092
            .sidebar('hide', function() {
16093
              callbackCount++;
16094
              if(callbackCount == sidebarCount) {
16095
                callback();
16096
              }
16097
            })
16098
          ;
16099
        },
16100
16101
        toggle: function() {
16102
          module.verbose('Determining toggled direction');
16103
          if(module.is.hidden()) {
16104
            module.show();
16105
          }
16106
          else {
16107
            module.hide();
16108
          }
16109
        },
16110
16111
        pushPage: function(callback) {
16112
          var
16113
            transition = module.get.transition(),
16114
            $transition = (transition === 'overlay' || module.othersActive())
16115
              ? $module
16116
              : $pusher,
16117
            animate,
16118
            dim,
16119
            transitionEnd
16120
          ;
16121
          callback = $.isFunction(callback)
16122
            ? callback
16123
            : function(){}
16124
          ;
16125
          if(settings.transition == 'scale down') {
16126
            module.scrollToTop();
16127
          }
16128
          module.set.transition(transition);
16129
          module.repaint();
16130
          animate = function() {
16131
            module.bind.clickaway();
16132
            module.add.inlineCSS();
16133
            module.set.animating();
16134
            module.set.visible();
16135
          };
16136
          dim = function() {
16137
            module.set.dimmed();
16138
          };
16139
          transitionEnd = function(event) {
16140
            if( event.target == $transition[0] ) {
16141
              $transition.off(transitionEvent + elementNamespace, transitionEnd);
16142
              module.remove.animating();
16143
              module.bind.scrollLock();
16144
              callback.call(element);
16145
            }
16146
          };
16147
          $transition.off(transitionEvent + elementNamespace);
16148
          $transition.on(transitionEvent + elementNamespace, transitionEnd);
16149
          requestAnimationFrame(animate);
16150
          if(settings.dimPage && !module.othersVisible()) {
16151
            requestAnimationFrame(dim);
16152
          }
16153
        },
16154
16155
        pullPage: function(callback) {
16156
          var
16157
            transition = module.get.transition(),
16158
            $transition = (transition == 'overlay' || module.othersActive())
16159
              ? $module
16160
              : $pusher,
16161
            animate,
16162
            transitionEnd
16163
          ;
16164
          callback = $.isFunction(callback)
16165
            ? callback
16166
            : function(){}
16167
          ;
16168
          module.verbose('Removing context push state', module.get.direction());
16169
16170
          module.unbind.clickaway();
16171
          module.unbind.scrollLock();
16172
16173
          animate = function() {
16174
            module.set.transition(transition);
16175
            module.set.animating();
16176
            module.remove.visible();
16177
            if(settings.dimPage && !module.othersVisible()) {
16178
              $pusher.removeClass(className.dimmed);
16179
            }
16180
          };
16181
          transitionEnd = function(event) {
16182
            if( event.target == $transition[0] ) {
16183
              $transition.off(transitionEvent + elementNamespace, transitionEnd);
16184
              module.remove.animating();
16185
              module.remove.transition();
16186
              module.remove.inlineCSS();
16187
              if(transition == 'scale down' || (settings.returnScroll && module.is.mobile()) ) {
16188
                module.scrollBack();
16189
              }
16190
              callback.call(element);
16191
            }
16192
          };
16193
          $transition.off(transitionEvent + elementNamespace);
16194
          $transition.on(transitionEvent + elementNamespace, transitionEnd);
16195
          requestAnimationFrame(animate);
16196
        },
16197
16198
        scrollToTop: function() {
16199
          module.verbose('Scrolling to top of page to avoid animation issues');
16200
          currentScroll = $(window).scrollTop();
16201
          $module.scrollTop(0);
16202
          window.scrollTo(0, 0);
16203
        },
16204
16205
        scrollBack: function() {
16206
          module.verbose('Scrolling back to original page position');
16207
          window.scrollTo(0, currentScroll);
16208
        },
16209
16210
        clear: {
16211
          cache: function() {
16212
            module.verbose('Clearing cached dimensions');
16213
            module.cache = {};
16214
          }
16215
        },
16216
16217
        set: {
16218
16219
          // ios only (scroll on html not document). This prevent auto-resize canvas/scroll in ios
16220
          // (This is no longer necessary in latest iOS)
16221
          ios: function() {
16222
            $html.addClass(className.ios);
16223
          },
16224
16225
          // container
16226
          pushed: function() {
16227
            $context.addClass(className.pushed);
16228
          },
16229
          pushable: function() {
16230
            $context.addClass(className.pushable);
16231
          },
16232
16233
          // pusher
16234
          dimmed: function() {
16235
            $pusher.addClass(className.dimmed);
16236
          },
16237
16238
          // sidebar
16239
          active: function() {
16240
            $module.addClass(className.active);
16241
          },
16242
          animating: function() {
16243
            $module.addClass(className.animating);
16244
          },
16245
          transition: function(transition) {
16246
            transition = transition || module.get.transition();
16247
            $module.addClass(transition);
16248
          },
16249
          direction: function(direction) {
16250
            direction = direction || module.get.direction();
16251
            $module.addClass(className[direction]);
16252
          },
16253
          visible: function() {
16254
            $module.addClass(className.visible);
16255
          },
16256
          overlay: function() {
16257
            $module.addClass(className.overlay);
16258
          }
16259
        },
16260
        remove: {
16261
16262
          inlineCSS: function() {
16263
            module.debug('Removing inline css styles', $style);
16264
            if($style && $style.length > 0) {
16265
              $style.remove();
16266
            }
16267
          },
16268
16269
          // ios scroll on html not document
16270
          ios: function() {
16271
            $html.removeClass(className.ios);
16272
          },
16273
16274
          // context
16275
          pushed: function() {
16276
            $context.removeClass(className.pushed);
16277
          },
16278
          pushable: function() {
16279
            $context.removeClass(className.pushable);
16280
          },
16281
16282
          // sidebar
16283
          active: function() {
16284
            $module.removeClass(className.active);
16285
          },
16286
          animating: function() {
16287
            $module.removeClass(className.animating);
16288
          },
16289
          transition: function(transition) {
16290
            transition = transition || module.get.transition();
16291
            $module.removeClass(transition);
16292
          },
16293
          direction: function(direction) {
16294
            direction = direction || module.get.direction();
16295
            $module.removeClass(className[direction]);
16296
          },
16297
          visible: function() {
16298
            $module.removeClass(className.visible);
16299
          },
16300
          overlay: function() {
16301
            $module.removeClass(className.overlay);
16302
          }
16303
        },
16304
16305
        get: {
16306
          direction: function() {
16307
            if($module.hasClass(className.top)) {
16308
              return className.top;
16309
            }
16310
            else if($module.hasClass(className.right)) {
16311
              return className.right;
16312
            }
16313
            else if($module.hasClass(className.bottom)) {
16314
              return className.bottom;
16315
            }
16316
            return className.left;
16317
          },
16318
          transition: function() {
16319
            var
16320
              direction = module.get.direction(),
16321
              transition
16322
            ;
16323
            transition = ( module.is.mobile() )
16324
              ? (settings.mobileTransition == 'auto')
16325
                ? settings.defaultTransition.mobile[direction]
16326
                : settings.mobileTransition
16327
              : (settings.transition == 'auto')
16328
                ? settings.defaultTransition.computer[direction]
16329
                : settings.transition
16330
            ;
16331
            module.verbose('Determined transition', transition);
16332
            return transition;
16333
          },
16334
          transitionEvent: function() {
16335
            var
16336
              element     = document.createElement('element'),
16337
              transitions = {
16338
                'transition'       :'transitionend',
16339
                'OTransition'      :'oTransitionEnd',
16340
                'MozTransition'    :'transitionend',
16341
                'WebkitTransition' :'webkitTransitionEnd'
16342
              },
16343
              transition
16344
            ;
16345
            for(transition in transitions){
16346
              if( element.style[transition] !== undefined ){
16347
                return transitions[transition];
16348
              }
16349
            }
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
16350
          }
16351
        },
16352
16353
        is: {
16354
16355
          ie: function() {
16356
            var
16357
              isIE11 = (!(window.ActiveXObject) && 'ActiveXObject' in window),
16358
              isIE   = ('ActiveXObject' in window)
16359
            ;
16360
            return (isIE11 || isIE);
16361
          },
16362
16363
          ios: function() {
16364
            var
16365
              userAgent      = navigator.userAgent,
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ 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...
16366
              isIOS          = userAgent.match(regExp.ios),
16367
              isMobileChrome = userAgent.match(regExp.mobileChrome)
16368
            ;
16369
            if(isIOS && !isMobileChrome) {
16370
              module.verbose('Browser was found to be iOS', userAgent);
16371
              return true;
16372
            }
16373
            else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
16374
              return false;
16375
            }
16376
          },
16377
          mobile: function() {
16378
            var
16379
              userAgent    = navigator.userAgent,
0 ignored issues
show
Bug introduced by
The variable navigator seems to be never declared. If this is a global, consider adding a /** global: navigator */ 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...
16380
              isMobile     = userAgent.match(regExp.mobile)
16381
            ;
16382
            if(isMobile) {
16383
              module.verbose('Browser was found to be mobile', userAgent);
16384
              return true;
16385
            }
16386
            else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
16387
              module.verbose('Browser is not mobile, using regular transition', userAgent);
16388
              return false;
16389
            }
16390
          },
16391
          hidden: function() {
16392
            return !module.is.visible();
16393
          },
16394
          visible: function() {
16395
            return $module.hasClass(className.visible);
16396
          },
16397
          // alias
16398
          open: function() {
16399
            return module.is.visible();
16400
          },
16401
          closed: function() {
16402
            return module.is.hidden();
16403
          },
16404
          vertical: function() {
16405
            return $module.hasClass(className.top);
16406
          },
16407
          animating: function() {
16408
            return $context.hasClass(className.animating);
16409
          },
16410
          rtl: function () {
16411
            if(module.cache.rtl === undefined) {
16412
              module.cache.rtl = ($module.css('direction') == 'rtl');
16413
            }
16414
            return module.cache.rtl;
16415
          }
16416
        },
16417
16418
        setting: function(name, value) {
16419
          module.debug('Changing setting', name, value);
16420
          if( $.isPlainObject(name) ) {
16421
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
16422
          }
16423
          else if(value !== undefined) {
16424
            if($.isPlainObject(settings[name])) {
16425
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
16426
            }
16427
            else {
16428
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
16429
            }
16430
          }
16431
          else {
16432
            return settings[name];
16433
          }
16434
        },
16435
        internal: function(name, value) {
16436
          if( $.isPlainObject(name) ) {
16437
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
16438
          }
16439
          else if(value !== undefined) {
16440
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
16441
          }
16442
          else {
16443
            return module[name];
16444
          }
16445
        },
16446
        debug: function() {
16447
          if(!settings.silent && settings.debug) {
16448
            if(settings.performance) {
16449
              module.performance.log(arguments);
16450
            }
16451
            else {
16452
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
16453
              module.debug.apply(console, arguments);
16454
            }
16455
          }
16456
        },
16457
        verbose: function() {
16458
          if(!settings.silent && settings.verbose && settings.debug) {
16459
            if(settings.performance) {
16460
              module.performance.log(arguments);
16461
            }
16462
            else {
16463
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
16464
              module.verbose.apply(console, arguments);
16465
            }
16466
          }
16467
        },
16468
        error: function() {
16469
          if(!settings.silent) {
16470
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
16471
            module.error.apply(console, arguments);
16472
          }
16473
        },
16474
        performance: {
16475
          log: function(message) {
16476
            var
16477
              currentTime,
16478
              executionTime,
16479
              previousTime
16480
            ;
16481
            if(settings.performance) {
16482
              currentTime   = new Date().getTime();
16483
              previousTime  = time || currentTime;
16484
              executionTime = currentTime - previousTime;
16485
              time          = currentTime;
16486
              performance.push({
16487
                'Name'           : message[0],
16488
                'Arguments'      : [].slice.call(message, 1) || '',
16489
                'Element'        : element,
16490
                'Execution Time' : executionTime
16491
              });
16492
            }
16493
            clearTimeout(module.performance.timer);
16494
            module.performance.timer = setTimeout(module.performance.display, 500);
16495
          },
16496
          display: function() {
16497
            var
16498
              title = settings.name + ':',
16499
              totalTime = 0
16500
            ;
16501
            time = false;
16502
            clearTimeout(module.performance.timer);
16503
            $.each(performance, function(index, data) {
16504
              totalTime += data['Execution Time'];
16505
            });
16506
            title += ' ' + totalTime + 'ms';
16507
            if(moduleSelector) {
16508
              title += ' \'' + moduleSelector + '\'';
16509
            }
16510
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
16511
              console.groupCollapsed(title);
16512
              if(console.table) {
16513
                console.table(performance);
16514
              }
16515
              else {
16516
                $.each(performance, function(index, data) {
16517
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
16518
                });
16519
              }
16520
              console.groupEnd();
16521
            }
16522
            performance = [];
16523
          }
16524
        },
16525
        invoke: function(query, passedArguments, context) {
16526
          var
16527
            object = instance,
16528
            maxDepth,
16529
            found,
16530
            response
16531
          ;
16532
          passedArguments = passedArguments || queryArguments;
16533
          context         = element         || context;
16534
          if(typeof query == 'string' && object !== undefined) {
16535
            query    = query.split(/[\. ]/);
16536
            maxDepth = query.length - 1;
16537
            $.each(query, function(depth, value) {
16538
              var camelCaseValue = (depth != maxDepth)
16539
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
16540
                : query
16541
              ;
16542
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
16543
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
16544
              }
16545
              else if( object[camelCaseValue] !== undefined ) {
16546
                found = object[camelCaseValue];
16547
                return false;
16548
              }
16549
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
16550
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
16551
              }
16552
              else if( object[value] !== undefined ) {
16553
                found = object[value];
16554
                return false;
16555
              }
16556
              else {
16557
                module.error(error.method, query);
16558
                return false;
16559
              }
16560
            });
16561
          }
16562
          if ( $.isFunction( found ) ) {
16563
            response = found.apply(context, passedArguments);
16564
          }
16565
          else if(found !== undefined) {
16566
            response = found;
16567
          }
16568
          if($.isArray(returnedValue)) {
16569
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 16565 is false. Are you sure the function push handles undefined variables?
Loading history...
16570
          }
16571
          else if(returnedValue !== undefined) {
16572
            returnedValue = [returnedValue, response];
16573
          }
16574
          else if(response !== undefined) {
16575
            returnedValue = response;
16576
          }
16577
          return found;
16578
        }
16579
      }
16580
    ;
16581
16582
    if(methodInvoked) {
16583
      if(instance === undefined) {
16584
        module.initialize();
16585
      }
16586
      module.invoke(query);
16587
    }
16588
    else {
16589
      if(instance !== undefined) {
16590
        module.invoke('destroy');
16591
      }
16592
      module.initialize();
16593
    }
16594
  });
16595
16596
  return (returnedValue !== undefined)
16597
    ? returnedValue
16598
    : this
16599
  ;
16600
};
16601
16602
$.fn.sidebar.settings = {
16603
16604
  name              : 'Sidebar',
16605
  namespace         : 'sidebar',
16606
16607
  silent            : false,
16608
  debug             : false,
16609
  verbose           : false,
16610
  performance       : true,
16611
16612
  transition        : 'auto',
16613
  mobileTransition  : 'auto',
16614
16615
  defaultTransition : {
16616
    computer: {
16617
      left   : 'uncover',
16618
      right  : 'uncover',
16619
      top    : 'overlay',
16620
      bottom : 'overlay'
16621
    },
16622
    mobile: {
16623
      left   : 'uncover',
16624
      right  : 'uncover',
16625
      top    : 'overlay',
16626
      bottom : 'overlay'
16627
    }
16628
  },
16629
16630
  context           : 'body',
16631
  exclusive         : false,
16632
  closable          : true,
16633
  dimPage           : true,
16634
  scrollLock        : false,
16635
  returnScroll      : false,
16636
  delaySetup        : false,
16637
16638
  duration          : 500,
16639
16640
  onChange          : function(){},
16641
  onShow            : function(){},
16642
  onHide            : function(){},
16643
16644
  onHidden          : function(){},
16645
  onVisible         : function(){},
16646
16647
  className         : {
16648
    active    : 'active',
16649
    animating : 'animating',
16650
    dimmed    : 'dimmed',
16651
    ios       : 'ios',
16652
    pushable  : 'pushable',
16653
    pushed    : 'pushed',
16654
    right     : 'right',
16655
    top       : 'top',
16656
    left      : 'left',
16657
    bottom    : 'bottom',
16658
    visible   : 'visible'
16659
  },
16660
16661
  selector: {
16662
    fixed   : '.fixed',
16663
    omitted : 'script, link, style, .ui.modal, .ui.dimmer, .ui.nag, .ui.fixed',
16664
    pusher  : '.pusher',
16665
    sidebar : '.ui.sidebar'
16666
  },
16667
16668
  regExp: {
16669
    ios          : /(iPad|iPhone|iPod)/g,
16670
    mobileChrome : /(CriOS)/g,
16671
    mobile       : /Mobile|iP(hone|od|ad)|Android|BlackBerry|IEMobile|Kindle|NetFront|Silk-Accelerated|(hpw|web)OS|Fennec|Minimo|Opera M(obi|ini)|Blazer|Dolfin|Dolphin|Skyfire|Zune/g
16672
  },
16673
16674
  error   : {
16675
    method       : 'The method you called is not defined.',
16676
    pusher       : 'Had to add pusher element. For optimal performance make sure body content is inside a pusher element',
16677
    movedSidebar : 'Had to move sidebar. For optimal performance make sure sidebar and pusher are direct children of your body tag',
16678
    overlay      : 'The overlay setting is no longer supported, use animation: overlay',
16679
    notFound     : 'There were no elements that matched the specified selector'
16680
  }
16681
16682
};
16683
16684
16685
})( jQuery, window, document );
16686
16687
/*!
16688
 * # Semantic UI 2.2.11 - Sticky
16689
 * http://github.com/semantic-org/semantic-ui/
16690
 *
16691
 *
16692
 * Released under the MIT license
16693
 * http://opensource.org/licenses/MIT
16694
 *
16695
 */
16696
16697 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
16698
16699
"use strict";
16700
16701
window = (typeof window != 'undefined' && window.Math == Math)
16702
  ? window
16703
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
16704
    ? self
16705
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
16706
;
16707
16708
$.fn.sticky = function(parameters) {
16709
  var
16710
    $allModules    = $(this),
16711
    moduleSelector = $allModules.selector || '',
16712
16713
    time           = new Date().getTime(),
16714
    performance    = [],
16715
16716
    query          = arguments[0],
16717
    methodInvoked  = (typeof query == 'string'),
16718
    queryArguments = [].slice.call(arguments, 1),
16719
    returnedValue
16720
  ;
16721
16722
  $allModules
16723
    .each(function() {
16724
      var
16725
        settings              = ( $.isPlainObject(parameters) )
16726
          ? $.extend(true, {}, $.fn.sticky.settings, parameters)
16727
          : $.extend({}, $.fn.sticky.settings),
16728
16729
        className             = settings.className,
16730
        namespace             = settings.namespace,
16731
        error                 = settings.error,
16732
16733
        eventNamespace        = '.' + namespace,
16734
        moduleNamespace       = 'module-' + namespace,
16735
16736
        $module               = $(this),
16737
        $window               = $(window),
16738
        $scroll               = $(settings.scrollContext),
16739
        $container,
16740
        $context,
16741
16742
        selector              = $module.selector || '',
0 ignored issues
show
Unused Code introduced by
The assignment to variable selector seems to be never used. Consider removing it.
Loading history...
16743
        instance              = $module.data(moduleNamespace),
16744
16745
        requestAnimationFrame = window.requestAnimationFrame
16746
          || window.mozRequestAnimationFrame
16747
          || window.webkitRequestAnimationFrame
16748
          || window.msRequestAnimationFrame
16749
          || function(callback) { setTimeout(callback, 0); },
16750
16751
        element         = this,
16752
16753
        documentObserver,
16754
        observer,
16755
        module
16756
      ;
16757
16758
      module      = {
16759
16760
        initialize: function() {
16761
16762
          module.determineContainer();
16763
          module.determineContext();
16764
          module.verbose('Initializing sticky', settings, $container);
16765
16766
          module.save.positions();
16767
          module.checkErrors();
16768
          module.bind.events();
16769
16770
          if(settings.observeChanges) {
16771
            module.observeChanges();
16772
          }
16773
          module.instantiate();
16774
        },
16775
16776
        instantiate: function() {
16777
          module.verbose('Storing instance of module', module);
16778
          instance = module;
16779
          $module
16780
            .data(moduleNamespace, module)
16781
          ;
16782
        },
16783
16784
        destroy: function() {
16785
          module.verbose('Destroying previous instance');
16786
          module.reset();
16787
          if(documentObserver) {
16788
            documentObserver.disconnect();
16789
          }
16790
          if(observer) {
16791
            observer.disconnect();
16792
          }
16793
          $window
16794
            .off('load' + eventNamespace, module.event.load)
16795
            .off('resize' + eventNamespace, module.event.resize)
16796
          ;
16797
          $scroll
16798
            .off('scrollchange' + eventNamespace, module.event.scrollchange)
16799
          ;
16800
          $module.removeData(moduleNamespace);
16801
        },
16802
16803
        observeChanges: function() {
16804
          if('MutationObserver' in window) {
16805
            documentObserver = new MutationObserver(module.event.documentChanged);
0 ignored issues
show
Bug introduced by
The variable MutationObserver seems to be never declared. If this is a global, consider adding a /** global: MutationObserver */ 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...
16806
            observer         = new MutationObserver(module.event.changed);
16807
            documentObserver.observe(document, {
16808
              childList : true,
16809
              subtree   : true
16810
            });
16811
            observer.observe(element, {
16812
              childList : true,
16813
              subtree   : true
16814
            });
16815
            observer.observe($context[0], {
16816
              childList : true,
16817
              subtree   : true
16818
            });
16819
            module.debug('Setting up mutation observer', observer);
16820
          }
16821
        },
16822
16823
        determineContainer: function() {
16824
          if(settings.container) {
16825
            $container = $(settings.container);
16826
          }
16827
          else {
16828
            $container = $module.offsetParent();
16829
          }
16830
        },
16831
16832
        determineContext: function() {
16833
          if(settings.context) {
16834
            $context = $(settings.context);
16835
          }
16836
          else {
16837
            $context = $container;
16838
          }
16839
          if($context.length === 0) {
16840
            module.error(error.invalidContext, settings.context, $module);
16841
            return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
16842
          }
16843
        },
16844
16845
        checkErrors: function() {
16846
          if( module.is.hidden() ) {
16847
            module.error(error.visible, $module);
16848
          }
16849
          if(module.cache.element.height > module.cache.context.height) {
16850
            module.reset();
16851
            module.error(error.elementSize, $module);
16852
            return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
16853
          }
16854
        },
16855
16856
        bind: {
16857
          events: function() {
16858
            $window
16859
              .on('load' + eventNamespace, module.event.load)
16860
              .on('resize' + eventNamespace, module.event.resize)
16861
            ;
16862
            // pub/sub pattern
16863
            $scroll
16864
              .off('scroll' + eventNamespace)
16865
              .on('scroll' + eventNamespace, module.event.scroll)
16866
              .on('scrollchange' + eventNamespace, module.event.scrollchange)
16867
            ;
16868
          }
16869
        },
16870
16871
        event: {
16872
          changed: function(mutations) {
16873
            clearTimeout(module.timer);
16874
            module.timer = setTimeout(function() {
16875
              module.verbose('DOM tree modified, updating sticky menu', mutations);
16876
              module.refresh();
16877
            }, 100);
16878
          },
16879
          documentChanged: function(mutations) {
16880
            [].forEach.call(mutations, function(mutation) {
16881
              if(mutation.removedNodes) {
16882
                [].forEach.call(mutation.removedNodes, function(node) {
16883
                  if(node == element || $(node).find(element).length > 0) {
16884
                    module.debug('Element removed from DOM, tearing down events');
16885
                    module.destroy();
16886
                  }
16887
                });
16888
              }
16889
            });
16890
          },
16891
          load: function() {
16892
            module.verbose('Page contents finished loading');
16893
            requestAnimationFrame(module.refresh);
16894
          },
16895
          resize: function() {
16896
            module.verbose('Window resized');
16897
            requestAnimationFrame(module.refresh);
16898
          },
16899
          scroll: function() {
16900
            requestAnimationFrame(function() {
16901
              $scroll.triggerHandler('scrollchange' + eventNamespace, $scroll.scrollTop() );
16902
            });
16903
          },
16904
          scrollchange: function(event, scrollPosition) {
16905
            module.stick(scrollPosition);
16906
            settings.onScroll.call(element);
16907
          }
16908
        },
16909
16910
        refresh: function(hardRefresh) {
16911
          module.reset();
16912
          if(!settings.context) {
16913
            module.determineContext();
16914
          }
16915
          if(hardRefresh) {
16916
            module.determineContainer();
16917
          }
16918
          module.save.positions();
16919
          module.stick();
16920
          settings.onReposition.call(element);
16921
        },
16922
16923
        supports: {
16924
          sticky: function() {
16925
            var
16926
              $element = $('<div/>'),
16927
              element = $element[0]
0 ignored issues
show
Unused Code introduced by
The variable element seems to be never used. Consider removing it.
Loading history...
16928
            ;
16929
            $element.addClass(className.supported);
16930
            return($element.css('position').match('sticky'));
16931
          }
16932
        },
16933
16934
        save: {
16935
          lastScroll: function(scroll) {
16936
            module.lastScroll = scroll;
16937
          },
16938
          elementScroll: function(scroll) {
16939
            module.elementScroll = scroll;
16940
          },
16941
          positions: function() {
16942
            var
16943
              scrollContext = {
16944
                height : $scroll.height()
16945
              },
16946
              element = {
16947
                margin: {
16948
                  top    : parseInt($module.css('margin-top'), 10),
16949
                  bottom : parseInt($module.css('margin-bottom'), 10),
16950
                },
16951
                offset : $module.offset(),
16952
                width  : $module.outerWidth(),
16953
                height : $module.outerHeight()
16954
              },
16955
              context = {
16956
                offset : $context.offset(),
16957
                height : $context.outerHeight()
16958
              },
16959
              container = {
0 ignored issues
show
Unused Code introduced by
The variable container seems to be never used. Consider removing it.
Loading history...
16960
                height: $container.outerHeight()
16961
              }
16962
            ;
16963
            if( !module.is.standardScroll() ) {
16964
              module.debug('Non-standard scroll. Removing scroll offset from element offset');
16965
16966
              scrollContext.top  = $scroll.scrollTop();
16967
              scrollContext.left = $scroll.scrollLeft();
16968
16969
              element.offset.top  += scrollContext.top;
16970
              context.offset.top  += scrollContext.top;
16971
              element.offset.left += scrollContext.left;
16972
              context.offset.left += scrollContext.left;
16973
            }
16974
            module.cache = {
16975
              fits          : ( (element.height + settings.offset) <= scrollContext.height),
16976
              sameHeight    : (element.height == context.height),
16977
              scrollContext : {
16978
                height : scrollContext.height
16979
              },
16980
              element: {
16981
                margin : element.margin,
16982
                top    : element.offset.top - element.margin.top,
16983
                left   : element.offset.left,
16984
                width  : element.width,
16985
                height : element.height,
16986
                bottom : element.offset.top + element.height
16987
              },
16988
              context: {
16989
                top           : context.offset.top,
16990
                height        : context.height,
16991
                bottom        : context.offset.top + context.height
16992
              }
16993
            };
16994
            module.set.containerSize();
16995
16996
            module.stick();
16997
            module.debug('Caching element positions', module.cache);
16998
          }
16999
        },
17000
17001
        get: {
17002
          direction: function(scroll) {
17003
            var
17004
              direction = 'down'
17005
            ;
17006
            scroll = scroll || $scroll.scrollTop();
17007
            if(module.lastScroll !== undefined) {
17008
              if(module.lastScroll < scroll) {
17009
                direction = 'down';
17010
              }
17011
              else if(module.lastScroll > scroll) {
17012
                direction = 'up';
17013
              }
17014
            }
17015
            return direction;
17016
          },
17017
          scrollChange: function(scroll) {
17018
            scroll = scroll || $scroll.scrollTop();
17019
            return (module.lastScroll)
17020
              ? (scroll - module.lastScroll)
17021
              : 0
17022
            ;
17023
          },
17024
          currentElementScroll: function() {
17025
            if(module.elementScroll) {
17026
              return module.elementScroll;
17027
            }
17028
            return ( module.is.top() )
17029
              ? Math.abs(parseInt($module.css('top'), 10))    || 0
17030
              : Math.abs(parseInt($module.css('bottom'), 10)) || 0
17031
            ;
17032
          },
17033
17034
          elementScroll: function(scroll) {
17035
            scroll = scroll || $scroll.scrollTop();
17036
            var
17037
              element        = module.cache.element,
17038
              scrollContext  = module.cache.scrollContext,
17039
              delta          = module.get.scrollChange(scroll),
17040
              maxScroll      = (element.height - scrollContext.height + settings.offset),
17041
              elementScroll  = module.get.currentElementScroll(),
17042
              possibleScroll = (elementScroll + delta)
17043
            ;
17044
            if(module.cache.fits || possibleScroll < 0) {
17045
              elementScroll = 0;
17046
            }
17047
            else if(possibleScroll > maxScroll ) {
17048
              elementScroll = maxScroll;
17049
            }
17050
            else {
17051
              elementScroll = possibleScroll;
17052
            }
17053
            return elementScroll;
17054
          }
17055
        },
17056
17057
        remove: {
17058
          lastScroll: function() {
17059
            delete module.lastScroll;
17060
          },
17061
          elementScroll: function(scroll) {
0 ignored issues
show
Unused Code introduced by
The parameter scroll is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
17062
            delete module.elementScroll;
17063
          },
17064
          minimumSize: function() {
17065
            $container
17066
              .css('min-height', '')
17067
            ;
17068
          },
17069
          offset: function() {
17070
            $module.css('margin-top', '');
17071
          }
17072
        },
17073
17074
        set: {
17075
          offset: function() {
17076
            module.verbose('Setting offset on element', settings.offset);
17077
            $module
17078
              .css('margin-top', settings.offset)
17079
            ;
17080
          },
17081
          containerSize: function() {
17082
            var
17083
              tagName = $container.get(0).tagName
17084
            ;
17085
            if(tagName === 'HTML' || tagName == 'body') {
17086
              // this can trigger for too many reasons
17087
              //module.error(error.container, tagName, $module);
17088
              module.determineContainer();
17089
            }
17090
            else {
17091
              if( Math.abs($container.outerHeight() - module.cache.context.height) > settings.jitter) {
17092
                module.debug('Context has padding, specifying exact height for container', module.cache.context.height);
17093
                $container.css({
17094
                  height: module.cache.context.height
17095
                });
17096
              }
17097
            }
17098
          },
17099
          minimumSize: function() {
17100
            var
17101
              element   = module.cache.element
17102
            ;
17103
            $container
17104
              .css('min-height', element.height)
17105
            ;
17106
          },
17107
          scroll: function(scroll) {
17108
            module.debug('Setting scroll on element', scroll);
17109
            if(module.elementScroll == scroll) {
17110
              return;
17111
            }
17112
            if( module.is.top() ) {
17113
              $module
17114
                .css('bottom', '')
17115
                .css('top', -scroll)
17116
              ;
17117
            }
17118
            if( module.is.bottom() ) {
17119
              $module
17120
                .css('top', '')
17121
                .css('bottom', scroll)
17122
              ;
17123
            }
17124
          },
17125
          size: function() {
17126
            if(module.cache.element.height !== 0 && module.cache.element.width !== 0) {
17127
              element.style.setProperty('width',  module.cache.element.width  + 'px', 'important');
17128
              element.style.setProperty('height', module.cache.element.height + 'px', 'important');
17129
            }
17130
          }
17131
        },
17132
17133
        is: {
17134
          standardScroll: function() {
17135
            return ($scroll[0] == window);
17136
          },
17137
          top: function() {
17138
            return $module.hasClass(className.top);
17139
          },
17140
          bottom: function() {
17141
            return $module.hasClass(className.bottom);
17142
          },
17143
          initialPosition: function() {
17144
            return (!module.is.fixed() && !module.is.bound());
17145
          },
17146
          hidden: function() {
17147
            return (!$module.is(':visible'));
17148
          },
17149
          bound: function() {
17150
            return $module.hasClass(className.bound);
17151
          },
17152
          fixed: function() {
17153
            return $module.hasClass(className.fixed);
17154
          }
17155
        },
17156
17157
        stick: function(scroll) {
17158
          var
17159
            cachedPosition = scroll || $scroll.scrollTop(),
17160
            cache          = module.cache,
17161
            fits           = cache.fits,
17162
            sameHeight     = cache.sameHeight,
17163
            element        = cache.element,
17164
            scrollContext  = cache.scrollContext,
17165
            context        = cache.context,
17166
            offset         = (module.is.bottom() && settings.pushing)
17167
              ? settings.bottomOffset
17168
              : settings.offset,
17169
            scroll         = {
17170
              top    : cachedPosition + offset,
17171
              bottom : cachedPosition + offset + scrollContext.height
17172
            },
17173
            direction      = module.get.direction(scroll.top),
0 ignored issues
show
Unused Code introduced by
The assignment to variable direction seems to be never used. Consider removing it.
Loading history...
17174
            elementScroll  = (fits)
17175
              ? 0
17176
              : module.get.elementScroll(scroll.top),
17177
17178
            // shorthand
17179
            doesntFit      = !fits,
17180
            elementVisible = (element.height !== 0)
17181
          ;
17182
          if(elementVisible && !sameHeight) {
17183
17184
            if( module.is.initialPosition() ) {
17185
              if(scroll.top >= context.bottom) {
17186
                module.debug('Initial element position is bottom of container');
17187
                module.bindBottom();
17188
              }
17189
              else if(scroll.top > element.top) {
17190
                if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
17191
                  module.debug('Initial element position is bottom of container');
17192
                  module.bindBottom();
17193
                }
17194
                else {
17195
                  module.debug('Initial element position is fixed');
17196
                  module.fixTop();
17197
                }
17198
              }
17199
17200
            }
17201
            else if( module.is.fixed() ) {
17202
17203
              // currently fixed top
17204
              if( module.is.top() ) {
17205
                if( scroll.top <= element.top ) {
17206
                  module.debug('Fixed element reached top of container');
17207
                  module.setInitialPosition();
17208
                }
17209
                else if( (element.height + scroll.top - elementScroll) >= context.bottom ) {
17210
                  module.debug('Fixed element reached bottom of container');
17211
                  module.bindBottom();
17212
                }
17213
                // scroll element if larger than screen
17214
                else if(doesntFit) {
17215
                  module.set.scroll(elementScroll);
17216
                  module.save.lastScroll(scroll.top);
17217
                  module.save.elementScroll(elementScroll);
17218
                }
17219
              }
17220
17221
              // currently fixed bottom
17222
              else if(module.is.bottom() ) {
17223
17224
                // top edge
17225
                if( (scroll.bottom - element.height) <= element.top) {
17226
                  module.debug('Bottom fixed rail has reached top of container');
17227
                  module.setInitialPosition();
17228
                }
17229
                // bottom edge
17230
                else if(scroll.bottom >= context.bottom) {
17231
                  module.debug('Bottom fixed rail has reached bottom of container');
17232
                  module.bindBottom();
17233
                }
17234
                // scroll element if larger than screen
17235
                else if(doesntFit) {
17236
                  module.set.scroll(elementScroll);
17237
                  module.save.lastScroll(scroll.top);
17238
                  module.save.elementScroll(elementScroll);
17239
                }
17240
17241
              }
17242
            }
17243
            else if( module.is.bottom() ) {
17244
              if( scroll.top <= element.top ) {
17245
                module.debug('Jumped from bottom fixed to top fixed, most likely used home/end button');
17246
                module.setInitialPosition();
17247
              }
17248
              else {
17249
                if(settings.pushing) {
17250
                  if(module.is.bound() && scroll.bottom <= context.bottom ) {
17251
                    module.debug('Fixing bottom attached element to bottom of browser.');
17252
                    module.fixBottom();
17253
                  }
17254
                }
17255
                else {
17256
                  if(module.is.bound() && (scroll.top <= context.bottom - element.height) ) {
17257
                    module.debug('Fixing bottom attached element to top of browser.');
17258
                    module.fixTop();
17259
                  }
17260
                }
17261
              }
17262
            }
17263
          }
17264
        },
17265
17266
        bindTop: function() {
17267
          module.debug('Binding element to top of parent container');
17268
          module.remove.offset();
17269
          $module
17270
            .css({
17271
              left         : '',
17272
              top          : '',
17273
              marginBottom : ''
17274
            })
17275
            .removeClass(className.fixed)
17276
            .removeClass(className.bottom)
17277
            .addClass(className.bound)
17278
            .addClass(className.top)
17279
          ;
17280
          settings.onTop.call(element);
17281
          settings.onUnstick.call(element);
17282
        },
17283
        bindBottom: function() {
17284
          module.debug('Binding element to bottom of parent container');
17285
          module.remove.offset();
17286
          $module
17287
            .css({
17288
              left         : '',
17289
              top          : ''
17290
            })
17291
            .removeClass(className.fixed)
17292
            .removeClass(className.top)
17293
            .addClass(className.bound)
17294
            .addClass(className.bottom)
17295
          ;
17296
          settings.onBottom.call(element);
17297
          settings.onUnstick.call(element);
17298
        },
17299
17300
        setInitialPosition: function() {
17301
          module.debug('Returning to initial position');
17302
          module.unfix();
17303
          module.unbind();
17304
        },
17305
17306
17307
        fixTop: function() {
17308
          module.debug('Fixing element to top of page');
17309
          if(settings.setSize) {
17310
            module.set.size();
17311
          }
17312
          module.set.minimumSize();
17313
          module.set.offset();
17314
          $module
17315
            .css({
17316
              left         : module.cache.element.left,
17317
              bottom       : '',
17318
              marginBottom : ''
17319
            })
17320
            .removeClass(className.bound)
17321
            .removeClass(className.bottom)
17322
            .addClass(className.fixed)
17323
            .addClass(className.top)
17324
          ;
17325
          settings.onStick.call(element);
17326
        },
17327
17328
        fixBottom: function() {
17329
          module.debug('Sticking element to bottom of page');
17330
          if(settings.setSize) {
17331
            module.set.size();
17332
          }
17333
          module.set.minimumSize();
17334
          module.set.offset();
17335
          $module
17336
            .css({
17337
              left         : module.cache.element.left,
17338
              bottom       : '',
17339
              marginBottom : ''
17340
            })
17341
            .removeClass(className.bound)
17342
            .removeClass(className.top)
17343
            .addClass(className.fixed)
17344
            .addClass(className.bottom)
17345
          ;
17346
          settings.onStick.call(element);
17347
        },
17348
17349
        unbind: function() {
17350
          if( module.is.bound() ) {
17351
            module.debug('Removing container bound position on element');
17352
            module.remove.offset();
17353
            $module
17354
              .removeClass(className.bound)
17355
              .removeClass(className.top)
17356
              .removeClass(className.bottom)
17357
            ;
17358
          }
17359
        },
17360
17361
        unfix: function() {
17362
          if( module.is.fixed() ) {
17363
            module.debug('Removing fixed position on element');
17364
            module.remove.minimumSize();
17365
            module.remove.offset();
17366
            $module
17367
              .removeClass(className.fixed)
17368
              .removeClass(className.top)
17369
              .removeClass(className.bottom)
17370
            ;
17371
            settings.onUnstick.call(element);
17372
          }
17373
        },
17374
17375
        reset: function() {
17376
          module.debug('Resetting elements position');
17377
          module.unbind();
17378
          module.unfix();
17379
          module.resetCSS();
17380
          module.remove.offset();
17381
          module.remove.lastScroll();
17382
        },
17383
17384
        resetCSS: function() {
17385
          $module
17386
            .css({
17387
              width  : '',
17388
              height : ''
17389
            })
17390
          ;
17391
          $container
17392
            .css({
17393
              height: ''
17394
            })
17395
          ;
17396
        },
17397
17398
        setting: function(name, value) {
17399
          if( $.isPlainObject(name) ) {
17400
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
17401
          }
17402
          else if(value !== undefined) {
17403
            settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
17404
          }
17405
          else {
17406
            return settings[name];
17407
          }
17408
        },
17409
        internal: function(name, value) {
17410
          if( $.isPlainObject(name) ) {
17411
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
17412
          }
17413
          else if(value !== undefined) {
17414
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
17415
          }
17416
          else {
17417
            return module[name];
17418
          }
17419
        },
17420
        debug: function() {
17421
          if(!settings.silent && settings.debug) {
17422
            if(settings.performance) {
17423
              module.performance.log(arguments);
17424
            }
17425
            else {
17426
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
17427
              module.debug.apply(console, arguments);
17428
            }
17429
          }
17430
        },
17431
        verbose: function() {
17432
          if(!settings.silent && settings.verbose && settings.debug) {
17433
            if(settings.performance) {
17434
              module.performance.log(arguments);
17435
            }
17436
            else {
17437
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
17438
              module.verbose.apply(console, arguments);
17439
            }
17440
          }
17441
        },
17442
        error: function() {
17443
          if(!settings.silent) {
17444
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
17445
            module.error.apply(console, arguments);
17446
          }
17447
        },
17448
        performance: {
17449
          log: function(message) {
17450
            var
17451
              currentTime,
17452
              executionTime,
17453
              previousTime
17454
            ;
17455
            if(settings.performance) {
17456
              currentTime   = new Date().getTime();
17457
              previousTime  = time || currentTime;
17458
              executionTime = currentTime - previousTime;
17459
              time          = currentTime;
17460
              performance.push({
17461
                'Name'           : message[0],
17462
                'Arguments'      : [].slice.call(message, 1) || '',
17463
                'Element'        : element,
17464
                'Execution Time' : executionTime
17465
              });
17466
            }
17467
            clearTimeout(module.performance.timer);
17468
            module.performance.timer = setTimeout(module.performance.display, 0);
17469
          },
17470
          display: function() {
17471
            var
17472
              title = settings.name + ':',
17473
              totalTime = 0
17474
            ;
17475
            time = false;
17476
            clearTimeout(module.performance.timer);
17477
            $.each(performance, function(index, data) {
17478
              totalTime += data['Execution Time'];
17479
            });
17480
            title += ' ' + totalTime + 'ms';
17481
            if(moduleSelector) {
17482
              title += ' \'' + moduleSelector + '\'';
17483
            }
17484
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
17485
              console.groupCollapsed(title);
17486
              if(console.table) {
17487
                console.table(performance);
17488
              }
17489
              else {
17490
                $.each(performance, function(index, data) {
17491
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
17492
                });
17493
              }
17494
              console.groupEnd();
17495
            }
17496
            performance = [];
17497
          }
17498
        },
17499
        invoke: function(query, passedArguments, context) {
17500
          var
17501
            object = instance,
17502
            maxDepth,
17503
            found,
17504
            response
17505
          ;
17506
          passedArguments = passedArguments || queryArguments;
17507
          context         = element         || context;
17508
          if(typeof query == 'string' && object !== undefined) {
17509
            query    = query.split(/[\. ]/);
17510
            maxDepth = query.length - 1;
17511
            $.each(query, function(depth, value) {
17512
              var camelCaseValue = (depth != maxDepth)
17513
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
17514
                : query
17515
              ;
17516
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
17517
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
17518
              }
17519
              else if( object[camelCaseValue] !== undefined ) {
17520
                found = object[camelCaseValue];
17521
                return false;
17522
              }
17523
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
17524
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
17525
              }
17526
              else if( object[value] !== undefined ) {
17527
                found = object[value];
17528
                return false;
17529
              }
17530
              else {
17531
                return false;
17532
              }
17533
            });
17534
          }
17535
          if ( $.isFunction( found ) ) {
17536
            response = found.apply(context, passedArguments);
17537
          }
17538
          else if(found !== undefined) {
17539
            response = found;
17540
          }
17541
          if($.isArray(returnedValue)) {
17542
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 17538 is false. Are you sure the function push handles undefined variables?
Loading history...
17543
          }
17544
          else if(returnedValue !== undefined) {
17545
            returnedValue = [returnedValue, response];
17546
          }
17547
          else if(response !== undefined) {
17548
            returnedValue = response;
17549
          }
17550
          return found;
17551
        }
17552
      };
17553
17554
      if(methodInvoked) {
17555
        if(instance === undefined) {
17556
          module.initialize();
17557
        }
17558
        module.invoke(query);
17559
      }
17560
      else {
17561
        if(instance !== undefined) {
17562
          instance.invoke('destroy');
17563
        }
17564
        module.initialize();
17565
      }
17566
    })
17567
  ;
17568
17569
  return (returnedValue !== undefined)
17570
    ? returnedValue
17571
    : this
17572
  ;
17573
};
17574
17575
$.fn.sticky.settings = {
17576
17577
  name           : 'Sticky',
17578
  namespace      : 'sticky',
17579
17580
  silent         : false,
17581
  debug          : false,
17582
  verbose        : true,
17583
  performance    : true,
17584
17585
  // whether to stick in the opposite direction on scroll up
17586
  pushing        : false,
17587
17588
  context        : false,
17589
  container      : false,
17590
17591
  // Context to watch scroll events
17592
  scrollContext  : window,
17593
17594
  // Offset to adjust scroll
17595
  offset         : 0,
17596
17597
  // Offset to adjust scroll when attached to bottom of screen
17598
  bottomOffset   : 0,
17599
17600
  // will only set container height if difference between context and container is larger than this number
17601
  jitter         : 5,
17602
17603
  // set width of sticky element when it is fixed to page (used to make sure 100% width is maintained if no fixed size set)
17604
  setSize        : true,
17605
17606
  // Whether to automatically observe changes with Mutation Observers
17607
  observeChanges : false,
17608
17609
  // Called when position is recalculated
17610
  onReposition   : function(){},
17611
17612
  // Called on each scroll
17613
  onScroll       : function(){},
17614
17615
  // Called when element is stuck to viewport
17616
  onStick        : function(){},
17617
17618
  // Called when element is unstuck from viewport
17619
  onUnstick      : function(){},
17620
17621
  // Called when element reaches top of context
17622
  onTop          : function(){},
17623
17624
  // Called when element reaches bottom of context
17625
  onBottom       : function(){},
17626
17627
  error         : {
17628
    container      : 'Sticky element must be inside a relative container',
17629
    visible        : 'Element is hidden, you must call refresh after element becomes visible. Use silent setting to surpress this warning in production.',
17630
    method         : 'The method you called is not defined.',
17631
    invalidContext : 'Context specified does not exist',
17632
    elementSize    : 'Sticky element is larger than its container, cannot create sticky.'
17633
  },
17634
17635
  className : {
17636
    bound     : 'bound',
17637
    fixed     : 'fixed',
17638
    supported : 'native',
17639
    top       : 'top',
17640
    bottom    : 'bottom'
17641
  }
17642
17643
};
17644
17645
})( jQuery, window, document );
17646
17647
/*!
17648
 * # Semantic UI 2.2.11 - Tab
17649
 * http://github.com/semantic-org/semantic-ui/
17650
 *
17651
 *
17652
 * Released under the MIT license
17653
 * http://opensource.org/licenses/MIT
17654
 *
17655
 */
17656
17657 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
17658
17659
"use strict";
17660
17661
window = (typeof window != 'undefined' && window.Math == Math)
17662
  ? window
17663
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
17664
    ? self
17665
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
17666
;
17667
17668
$.fn.tab = function(parameters) {
17669
17670
  var
17671
    // use window context if none specified
17672
    $allModules     = $.isFunction(this)
17673
        ? $(window)
17674
        : $(this),
17675
17676
    moduleSelector  = $allModules.selector || '',
17677
    time            = new Date().getTime(),
17678
    performance     = [],
17679
17680
    query           = arguments[0],
17681
    methodInvoked   = (typeof query == 'string'),
17682
    queryArguments  = [].slice.call(arguments, 1),
17683
17684
    initializedHistory = false,
17685
    returnedValue
17686
  ;
17687
17688
  $allModules
17689
    .each(function() {
17690
      var
17691
17692
        settings        = ( $.isPlainObject(parameters) )
17693
          ? $.extend(true, {}, $.fn.tab.settings, parameters)
17694
          : $.extend({}, $.fn.tab.settings),
17695
17696
        className       = settings.className,
17697
        metadata        = settings.metadata,
17698
        selector        = settings.selector,
17699
        error           = settings.error,
17700
17701
        eventNamespace  = '.' + settings.namespace,
17702
        moduleNamespace = 'module-' + settings.namespace,
17703
17704
        $module         = $(this),
17705
        $context,
17706
        $tabs,
17707
17708
        cache           = {},
17709
        firstLoad       = true,
17710
        recursionDepth  = 0,
17711
        element         = this,
17712
        instance        = $module.data(moduleNamespace),
17713
17714
        activeTabPath,
17715
        parameterArray,
17716
        module,
17717
17718
        historyEvent
17719
17720
      ;
17721
17722
      module = {
17723
17724
        initialize: function() {
17725
          module.debug('Initializing tab menu item', $module);
17726
          module.fix.callbacks();
17727
          module.determineTabs();
17728
17729
          module.debug('Determining tabs', settings.context, $tabs);
17730
          // set up automatic routing
17731
          if(settings.auto) {
17732
            module.set.auto();
17733
          }
17734
          module.bind.events();
17735
17736
          if(settings.history && !initializedHistory) {
17737
            module.initializeHistory();
17738
            initializedHistory = true;
17739
          }
17740
17741
          module.instantiate();
17742
        },
17743
17744
        instantiate: function () {
17745
          module.verbose('Storing instance of module', module);
17746
          instance = module;
17747
          $module
17748
            .data(moduleNamespace, module)
17749
          ;
17750
        },
17751
17752
        destroy: function() {
17753
          module.debug('Destroying tabs', $module);
17754
          $module
17755
            .removeData(moduleNamespace)
17756
            .off(eventNamespace)
17757
          ;
17758
        },
17759
17760
        bind: {
17761
          events: function() {
17762
            // if using $.tab don't add events
17763
            if( !$.isWindow( element ) ) {
17764
              module.debug('Attaching tab activation events to element', $module);
17765
              $module
17766
                .on('click' + eventNamespace, module.event.click)
17767
              ;
17768
            }
17769
          }
17770
        },
17771
17772
        determineTabs: function() {
17773
          var
17774
            $reference
17775
          ;
17776
17777
          // determine tab context
17778
          if(settings.context === 'parent') {
17779
            if($module.closest(selector.ui).length > 0) {
17780
              $reference = $module.closest(selector.ui);
17781
              module.verbose('Using closest UI element as parent', $reference);
17782
            }
17783
            else {
17784
              $reference = $module;
17785
            }
17786
            $context = $reference.parent();
17787
            module.verbose('Determined parent element for creating context', $context);
17788
          }
17789
          else if(settings.context) {
17790
            $context = $(settings.context);
17791
            module.verbose('Using selector for tab context', settings.context, $context);
17792
          }
17793
          else {
17794
            $context = $('body');
17795
          }
17796
          // find tabs
17797
          if(settings.childrenOnly) {
17798
            $tabs = $context.children(selector.tabs);
17799
            module.debug('Searching tab context children for tabs', $context, $tabs);
17800
          }
17801
          else {
17802
            $tabs = $context.find(selector.tabs);
17803
            module.debug('Searching tab context for tabs', $context, $tabs);
17804
          }
17805
        },
17806
17807
        fix: {
17808
          callbacks: function() {
17809
            if( $.isPlainObject(parameters) && (parameters.onTabLoad || parameters.onTabInit) ) {
17810
              if(parameters.onTabLoad) {
17811
                parameters.onLoad = parameters.onTabLoad;
17812
                delete parameters.onTabLoad;
17813
                module.error(error.legacyLoad, parameters.onLoad);
17814
              }
17815
              if(parameters.onTabInit) {
17816
                parameters.onFirstLoad = parameters.onTabInit;
17817
                delete parameters.onTabInit;
17818
                module.error(error.legacyInit, parameters.onFirstLoad);
17819
              }
17820
              settings = $.extend(true, {}, $.fn.tab.settings, parameters);
17821
            }
17822
          }
17823
        },
17824
17825
        initializeHistory: function() {
17826
          module.debug('Initializing page state');
17827
          if( $.address === undefined ) {
17828
            module.error(error.state);
17829
            return false;
17830
          }
17831
          else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
17832
            if(settings.historyType == 'state') {
17833
              module.debug('Using HTML5 to manage state');
17834
              if(settings.path !== false) {
17835
                $.address
17836
                  .history(true)
17837
                  .state(settings.path)
17838
                ;
17839
              }
17840
              else {
17841
                module.error(error.path);
17842
                return false;
17843
              }
17844
            }
17845
            $.address
17846
              .bind('change', module.event.history.change)
17847
            ;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
17848
          }
17849
        },
17850
17851
        event: {
17852
          click: function(event) {
17853
            var
17854
              tabPath = $(this).data(metadata.tab)
17855
            ;
17856
            if(tabPath !== undefined) {
17857
              if(settings.history) {
17858
                module.verbose('Updating page state', event);
17859
                $.address.value(tabPath);
17860
              }
17861
              else {
17862
                module.verbose('Changing tab', event);
17863
                module.changeTab(tabPath);
17864
              }
17865
              event.preventDefault();
17866
            }
17867
            else {
17868
              module.debug('No tab specified');
17869
            }
17870
          },
17871
          history: {
17872
            change: function(event) {
17873
              var
17874
                tabPath   = event.pathNames.join('/') || module.get.initialPath(),
17875
                pageTitle = settings.templates.determineTitle(tabPath) || false
17876
              ;
17877
              module.performance.display();
17878
              module.debug('History change event', tabPath, event);
17879
              historyEvent = event;
17880
              if(tabPath !== undefined) {
17881
                module.changeTab(tabPath);
17882
              }
17883
              if(pageTitle) {
17884
                $.address.title(pageTitle);
17885
              }
17886
            }
17887
          }
17888
        },
17889
17890
        refresh: function() {
17891
          if(activeTabPath) {
17892
            module.debug('Refreshing tab', activeTabPath);
17893
            module.changeTab(activeTabPath);
17894
          }
17895
        },
17896
17897
        cache: {
17898
17899
          read: function(cacheKey) {
17900
            return (cacheKey !== undefined)
17901
              ? cache[cacheKey]
17902
              : false
17903
            ;
17904
          },
17905
          add: function(cacheKey, content) {
17906
            cacheKey = cacheKey || activeTabPath;
17907
            module.debug('Adding cached content for', cacheKey);
17908
            cache[cacheKey] = content;
17909
          },
17910
          remove: function(cacheKey) {
17911
            cacheKey = cacheKey || activeTabPath;
17912
            module.debug('Removing cached content for', cacheKey);
17913
            delete cache[cacheKey];
17914
          }
17915
        },
17916
17917
        set: {
17918
          auto: function() {
17919
            var
17920
              url = (typeof settings.path == 'string')
17921
                ? settings.path.replace(/\/$/, '') + '/{$tab}'
17922
                : '/{$tab}'
17923
            ;
17924
            module.verbose('Setting up automatic tab retrieval from server', url);
17925
            if($.isPlainObject(settings.apiSettings)) {
17926
              settings.apiSettings.url = url;
17927
            }
17928
            else {
17929
              settings.apiSettings = {
17930
                url: url
17931
              };
17932
            }
17933
          },
17934
          loading: function(tabPath) {
17935
            var
17936
              $tab      = module.get.tabElement(tabPath),
17937
              isLoading = $tab.hasClass(className.loading)
17938
            ;
17939
            if(!isLoading) {
17940
              module.verbose('Setting loading state for', $tab);
17941
              $tab
17942
                .addClass(className.loading)
17943
                .siblings($tabs)
17944
                  .removeClass(className.active + ' ' + className.loading)
17945
              ;
17946
              if($tab.length > 0) {
17947
                settings.onRequest.call($tab[0], tabPath);
17948
              }
17949
            }
17950
          },
17951
          state: function(state) {
17952
            $.address.value(state);
17953
          }
17954
        },
17955
17956
        changeTab: function(tabPath) {
17957
          var
17958
            pushStateAvailable = (window.history && window.history.pushState),
17959
            shouldIgnoreLoad   = (pushStateAvailable && settings.ignoreFirstLoad && firstLoad),
17960
            remoteContent      = (settings.auto || $.isPlainObject(settings.apiSettings) ),
17961
            // only add default path if not remote content
17962
            pathArray = (remoteContent && !shouldIgnoreLoad)
17963
              ? module.utilities.pathToArray(tabPath)
17964
              : module.get.defaultPathArray(tabPath)
17965
          ;
17966
          tabPath = module.utilities.arrayToPath(pathArray);
17967
          $.each(pathArray, function(index, tab) {
17968
            var
17969
              currentPathArray   = pathArray.slice(0, index + 1),
17970
              currentPath        = module.utilities.arrayToPath(currentPathArray),
17971
17972
              isTab              = module.is.tab(currentPath),
17973
              isLastIndex        = (index + 1 == pathArray.length),
17974
17975
              $tab               = module.get.tabElement(currentPath),
17976
              $anchor,
17977
              nextPathArray,
17978
              nextPath,
17979
              isLastTab
17980
            ;
17981
            module.verbose('Looking for tab', tab);
17982
            if(isTab) {
17983
              module.verbose('Tab was found', tab);
17984
              // scope up
17985
              activeTabPath  = currentPath;
17986
              parameterArray = module.utilities.filterArray(pathArray, currentPathArray);
17987
17988
              if(isLastIndex) {
17989
                isLastTab = true;
17990
              }
17991
              else {
17992
                nextPathArray = pathArray.slice(0, index + 2);
17993
                nextPath      = module.utilities.arrayToPath(nextPathArray);
17994
                isLastTab     = ( !module.is.tab(nextPath) );
17995
                if(isLastTab) {
17996
                  module.verbose('Tab parameters found', nextPathArray);
17997
                }
17998
              }
17999
              if(isLastTab && remoteContent) {
18000
                if(!shouldIgnoreLoad) {
18001
                  module.activate.navigation(currentPath);
18002
                  module.fetch.content(currentPath, tabPath);
18003
                }
18004
                else {
18005
                  module.debug('Ignoring remote content on first tab load', currentPath);
18006
                  firstLoad = false;
18007
                  module.cache.add(tabPath, $tab.html());
18008
                  module.activate.all(currentPath);
18009
                  settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
18010
                  settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
18011
                }
18012
                return false;
18013
              }
18014
              else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
18015
                module.debug('Opened local tab', currentPath);
18016
                module.activate.all(currentPath);
18017
                if( !module.cache.read(currentPath) ) {
18018
                  module.cache.add(currentPath, true);
18019
                  module.debug('First time tab loaded calling tab init');
18020
                  settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
18021
                }
18022
                settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
18023
              }
18024
18025
            }
18026
            else if(tabPath.search('/') == -1 && tabPath !== '') {
18027
              // look for in page anchor
18028
              $anchor     = $('#' + tabPath + ', a[name="' + tabPath + '"]');
18029
              currentPath = $anchor.closest('[data-tab]').data(metadata.tab);
18030
              $tab        = module.get.tabElement(currentPath);
18031
              // if anchor exists use parent tab
18032
              if($anchor && $anchor.length > 0 && currentPath) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if $anchor && $anchor.length > 0 && currentPath is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
18033
                module.debug('Anchor link used, opening parent tab', $tab, $anchor);
18034
                if( !$tab.hasClass(className.active) ) {
18035
                  setTimeout(function() {
18036
                    module.scrollTo($anchor);
18037
                  }, 0);
18038
                }
18039
                module.activate.all(currentPath);
18040
                if( !module.cache.read(currentPath) ) {
18041
                  module.cache.add(currentPath, true);
18042
                  module.debug('First time tab loaded calling tab init');
18043
                  settings.onFirstLoad.call($tab[0], currentPath, parameterArray, historyEvent);
18044
                }
18045
                settings.onLoad.call($tab[0], currentPath, parameterArray, historyEvent);
18046
                return false;
18047
              }
18048
            }
18049
            else {
18050
              module.error(error.missingTab, $module, $context, currentPath);
18051
              return false;
18052
            }
18053
          });
18054
        },
18055
18056
        scrollTo: function($element) {
18057
          var
18058
            scrollOffset = ($element && $element.length > 0)
18059
              ? $element.offset().top
18060
              : false
18061
          ;
18062
          if(scrollOffset !== false) {
18063
            module.debug('Forcing scroll to an in-page link in a hidden tab', scrollOffset, $element);
18064
            $(document).scrollTop(scrollOffset);
18065
          }
18066
        },
18067
18068
        update: {
18069
          content: function(tabPath, html, evaluateScripts) {
18070
            var
18071
              $tab = module.get.tabElement(tabPath),
18072
              tab  = $tab[0]
18073
            ;
18074
            evaluateScripts = (evaluateScripts !== undefined)
18075
              ? evaluateScripts
18076
              : settings.evaluateScripts
18077
            ;
18078
            if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && typeof html !== 'string') {
18079
              $tab
18080
                .empty()
18081
                .append($(html).clone(true))
18082
              ;
18083
            }
18084
            else {
18085
              if(evaluateScripts) {
18086
                module.debug('Updating HTML and evaluating inline scripts', tabPath, html);
18087
                $tab.html(html);
18088
              }
18089
              else {
18090
                module.debug('Updating HTML', tabPath, html);
18091
                tab.innerHTML = html;
18092
              }
18093
            }
18094
          }
18095
        },
18096
18097
        fetch: {
18098
18099
          content: function(tabPath, fullTabPath) {
18100
            var
18101
              $tab        = module.get.tabElement(tabPath),
18102
              apiSettings = {
18103
                dataType         : 'html',
18104
                encodeParameters : false,
18105
                on               : 'now',
18106
                cache            : settings.alwaysRefresh,
18107
                headers          : {
18108
                  'X-Remote': true
18109
                },
18110
                onSuccess : function(response) {
18111
                  if(settings.cacheType == 'response') {
18112
                    module.cache.add(fullTabPath, response);
18113
                  }
18114
                  module.update.content(tabPath, response);
18115
                  if(tabPath == activeTabPath) {
18116
                    module.debug('Content loaded', tabPath);
18117
                    module.activate.tab(tabPath);
18118
                  }
18119
                  else {
18120
                    module.debug('Content loaded in background', tabPath);
18121
                  }
18122
                  settings.onFirstLoad.call($tab[0], tabPath, parameterArray, historyEvent);
18123
                  settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
18124
18125
                  if(settings.loadOnce) {
18126
                    module.cache.add(fullTabPath, true);
18127
                  }
18128
                  else if(typeof settings.cacheType == 'string' && settings.cacheType.toLowerCase() == 'dom' && $tab.children().length > 0) {
18129
                    setTimeout(function() {
18130
                      var
18131
                        $clone = $tab.children().clone(true)
18132
                      ;
18133
                      $clone = $clone.not('script');
18134
                      module.cache.add(fullTabPath, $clone);
18135
                    }, 0);
18136
                  }
18137
                  else {
18138
                    module.cache.add(fullTabPath, $tab.html());
18139
                  }
18140
                },
18141
                urlData: {
18142
                  tab: fullTabPath
18143
                }
18144
              },
18145
              request         = $tab.api('get request') || false,
18146
              existingRequest = ( request && request.state() === 'pending' ),
18147
              requestSettings,
18148
              cachedContent
18149
            ;
18150
18151
            fullTabPath   = fullTabPath || tabPath;
18152
            cachedContent = module.cache.read(fullTabPath);
18153
18154
18155
            if(settings.cache && cachedContent) {
18156
              module.activate.tab(tabPath);
18157
              module.debug('Adding cached content', fullTabPath);
18158
              if(!settings.loadOnce) {
18159
                if(settings.evaluateScripts == 'once') {
18160
                  module.update.content(tabPath, cachedContent, false);
18161
                }
18162
                else {
18163
                  module.update.content(tabPath, cachedContent);
18164
                }
18165
              }
18166
              settings.onLoad.call($tab[0], tabPath, parameterArray, historyEvent);
18167
            }
18168
            else if(existingRequest) {
18169
              module.set.loading(tabPath);
18170
              module.debug('Content is already loading', fullTabPath);
18171
            }
18172
            else if($.api !== undefined) {
18173
              requestSettings = $.extend(true, {}, settings.apiSettings, apiSettings);
18174
              module.debug('Retrieving remote content', fullTabPath, requestSettings);
18175
              module.set.loading(tabPath);
18176
              $tab.api(requestSettings);
18177
            }
18178
            else {
18179
              module.error(error.api);
18180
            }
18181
          }
18182
        },
18183
18184
        activate: {
18185
          all: function(tabPath) {
18186
            module.activate.tab(tabPath);
18187
            module.activate.navigation(tabPath);
18188
          },
18189
          tab: function(tabPath) {
18190
            var
18191
              $tab          = module.get.tabElement(tabPath),
18192
              $deactiveTabs = (settings.deactivate == 'siblings')
18193
                ? $tab.siblings($tabs)
18194
                : $tabs.not($tab),
18195
              isActive      = $tab.hasClass(className.active)
18196
            ;
18197
            module.verbose('Showing tab content for', $tab);
18198
            if(!isActive) {
18199
              $tab
18200
                .addClass(className.active)
18201
              ;
18202
              $deactiveTabs
18203
                .removeClass(className.active + ' ' + className.loading)
18204
              ;
18205
              if($tab.length > 0) {
18206
                settings.onVisible.call($tab[0], tabPath);
18207
              }
18208
            }
18209
          },
18210
          navigation: function(tabPath) {
18211
            var
18212
              $navigation         = module.get.navElement(tabPath),
18213
              $deactiveNavigation = (settings.deactivate == 'siblings')
18214
                ? $navigation.siblings($allModules)
18215
                : $allModules.not($navigation),
18216
              isActive    = $navigation.hasClass(className.active)
18217
            ;
18218
            module.verbose('Activating tab navigation for', $navigation, tabPath);
18219
            if(!isActive) {
18220
              $navigation
18221
                .addClass(className.active)
18222
              ;
18223
              $deactiveNavigation
18224
                .removeClass(className.active + ' ' + className.loading)
18225
              ;
18226
            }
18227
          }
18228
        },
18229
18230
        deactivate: {
18231
          all: function() {
18232
            module.deactivate.navigation();
18233
            module.deactivate.tabs();
18234
          },
18235
          navigation: function() {
18236
            $allModules
18237
              .removeClass(className.active)
18238
            ;
18239
          },
18240
          tabs: function() {
18241
            $tabs
18242
              .removeClass(className.active + ' ' + className.loading)
18243
            ;
18244
          }
18245
        },
18246
18247
        is: {
18248
          tab: function(tabName) {
18249
            return (tabName !== undefined)
18250
              ? ( module.get.tabElement(tabName).length > 0 )
18251
              : false
18252
            ;
18253
          }
18254
        },
18255
18256
        get: {
18257
          initialPath: function() {
18258
            return $allModules.eq(0).data(metadata.tab) || $tabs.eq(0).data(metadata.tab);
18259
          },
18260
          path: function() {
18261
            return $.address.value();
18262
          },
18263
          // adds default tabs to tab path
18264
          defaultPathArray: function(tabPath) {
18265
            return module.utilities.pathToArray( module.get.defaultPath(tabPath) );
18266
          },
18267
          defaultPath: function(tabPath) {
18268
            var
18269
              $defaultNav = $allModules.filter('[data-' + metadata.tab + '^="' + tabPath + '/"]').eq(0),
18270
              defaultTab  = $defaultNav.data(metadata.tab) || false
18271
            ;
18272
            if( defaultTab ) {
18273
              module.debug('Found default tab', defaultTab);
18274
              if(recursionDepth < settings.maxDepth) {
18275
                recursionDepth++;
18276
                return module.get.defaultPath(defaultTab);
18277
              }
18278
              module.error(error.recursion);
18279
            }
18280
            else {
18281
              module.debug('No default tabs found for', tabPath, $tabs);
18282
            }
18283
            recursionDepth = 0;
18284
            return tabPath;
18285
          },
18286
          navElement: function(tabPath) {
18287
            tabPath = tabPath || activeTabPath;
18288
            return $allModules.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
18289
          },
18290
          tabElement: function(tabPath) {
18291
            var
18292
              $fullPathTab,
18293
              $simplePathTab,
18294
              tabPathArray,
18295
              lastTab
18296
            ;
18297
            tabPath        = tabPath || activeTabPath;
18298
            tabPathArray   = module.utilities.pathToArray(tabPath);
18299
            lastTab        = module.utilities.last(tabPathArray);
18300
            $fullPathTab   = $tabs.filter('[data-' + metadata.tab + '="' + tabPath + '"]');
18301
            $simplePathTab = $tabs.filter('[data-' + metadata.tab + '="' + lastTab + '"]');
18302
            return ($fullPathTab.length > 0)
18303
              ? $fullPathTab
18304
              : $simplePathTab
18305
            ;
18306
          },
18307
          tab: function() {
18308
            return activeTabPath;
18309
          }
18310
        },
18311
18312
        utilities: {
18313
          filterArray: function(keepArray, removeArray) {
18314
            return $.grep(keepArray, function(keepValue) {
18315
              return ( $.inArray(keepValue, removeArray) == -1);
18316
            });
18317
          },
18318
          last: function(array) {
18319
            return $.isArray(array)
18320
              ? array[ array.length - 1]
18321
              : false
18322
            ;
18323
          },
18324
          pathToArray: function(pathName) {
18325
            if(pathName === undefined) {
18326
              pathName = activeTabPath;
18327
            }
18328
            return typeof pathName == 'string'
18329
              ? pathName.split('/')
18330
              : [pathName]
18331
            ;
18332
          },
18333
          arrayToPath: function(pathArray) {
18334
            return $.isArray(pathArray)
18335
              ? pathArray.join('/')
18336
              : false
18337
            ;
18338
          }
18339
        },
18340
18341
        setting: function(name, value) {
18342
          module.debug('Changing setting', name, value);
18343
          if( $.isPlainObject(name) ) {
18344
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
18345
          }
18346
          else if(value !== undefined) {
18347
            if($.isPlainObject(settings[name])) {
18348
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
18349
            }
18350
            else {
18351
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
18352
            }
18353
          }
18354
          else {
18355
            return settings[name];
18356
          }
18357
        },
18358
        internal: function(name, value) {
18359
          if( $.isPlainObject(name) ) {
18360
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
18361
          }
18362
          else if(value !== undefined) {
18363
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
18364
          }
18365
          else {
18366
            return module[name];
18367
          }
18368
        },
18369
        debug: function() {
18370
          if(!settings.silent && settings.debug) {
18371
            if(settings.performance) {
18372
              module.performance.log(arguments);
18373
            }
18374
            else {
18375
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
18376
              module.debug.apply(console, arguments);
18377
            }
18378
          }
18379
        },
18380
        verbose: function() {
18381
          if(!settings.silent && settings.verbose && settings.debug) {
18382
            if(settings.performance) {
18383
              module.performance.log(arguments);
18384
            }
18385
            else {
18386
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
18387
              module.verbose.apply(console, arguments);
18388
            }
18389
          }
18390
        },
18391
        error: function() {
18392
          if(!settings.silent) {
18393
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
18394
            module.error.apply(console, arguments);
18395
          }
18396
        },
18397
        performance: {
18398
          log: function(message) {
18399
            var
18400
              currentTime,
18401
              executionTime,
18402
              previousTime
18403
            ;
18404
            if(settings.performance) {
18405
              currentTime   = new Date().getTime();
18406
              previousTime  = time || currentTime;
18407
              executionTime = currentTime - previousTime;
18408
              time          = currentTime;
18409
              performance.push({
18410
                'Name'           : message[0],
18411
                'Arguments'      : [].slice.call(message, 1) || '',
18412
                'Element'        : element,
18413
                'Execution Time' : executionTime
18414
              });
18415
            }
18416
            clearTimeout(module.performance.timer);
18417
            module.performance.timer = setTimeout(module.performance.display, 500);
18418
          },
18419
          display: function() {
18420
            var
18421
              title = settings.name + ':',
18422
              totalTime = 0
18423
            ;
18424
            time = false;
18425
            clearTimeout(module.performance.timer);
18426
            $.each(performance, function(index, data) {
18427
              totalTime += data['Execution Time'];
18428
            });
18429
            title += ' ' + totalTime + 'ms';
18430
            if(moduleSelector) {
18431
              title += ' \'' + moduleSelector + '\'';
18432
            }
18433
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
18434
              console.groupCollapsed(title);
18435
              if(console.table) {
18436
                console.table(performance);
18437
              }
18438
              else {
18439
                $.each(performance, function(index, data) {
18440
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
18441
                });
18442
              }
18443
              console.groupEnd();
18444
            }
18445
            performance = [];
18446
          }
18447
        },
18448
        invoke: function(query, passedArguments, context) {
18449
          var
18450
            object = instance,
18451
            maxDepth,
18452
            found,
18453
            response
18454
          ;
18455
          passedArguments = passedArguments || queryArguments;
18456
          context         = element         || context;
18457
          if(typeof query == 'string' && object !== undefined) {
18458
            query    = query.split(/[\. ]/);
18459
            maxDepth = query.length - 1;
18460
            $.each(query, function(depth, value) {
18461
              var camelCaseValue = (depth != maxDepth)
18462
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
18463
                : query
18464
              ;
18465
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
18466
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
18467
              }
18468
              else if( object[camelCaseValue] !== undefined ) {
18469
                found = object[camelCaseValue];
18470
                return false;
18471
              }
18472
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
18473
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
18474
              }
18475
              else if( object[value] !== undefined ) {
18476
                found = object[value];
18477
                return false;
18478
              }
18479
              else {
18480
                module.error(error.method, query);
18481
                return false;
18482
              }
18483
            });
18484
          }
18485
          if ( $.isFunction( found ) ) {
18486
            response = found.apply(context, passedArguments);
18487
          }
18488
          else if(found !== undefined) {
18489
            response = found;
18490
          }
18491
          if($.isArray(returnedValue)) {
18492
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 18488 is false. Are you sure the function push handles undefined variables?
Loading history...
18493
          }
18494
          else if(returnedValue !== undefined) {
18495
            returnedValue = [returnedValue, response];
18496
          }
18497
          else if(response !== undefined) {
18498
            returnedValue = response;
18499
          }
18500
          return found;
18501
        }
18502
      };
18503
      if(methodInvoked) {
18504
        if(instance === undefined) {
18505
          module.initialize();
18506
        }
18507
        module.invoke(query);
18508
      }
18509
      else {
18510
        if(instance !== undefined) {
18511
          instance.invoke('destroy');
18512
        }
18513
        module.initialize();
18514
      }
18515
    })
18516
  ;
18517
  return (returnedValue !== undefined)
18518
    ? returnedValue
18519
    : this
18520
  ;
18521
18522
};
18523
18524
// shortcut for tabbed content with no defined navigation
18525
$.tab = function() {
18526
  $(window).tab.apply(this, arguments);
18527
};
18528
18529
$.fn.tab.settings = {
18530
18531
  name            : 'Tab',
18532
  namespace       : 'tab',
18533
18534
  silent          : false,
18535
  debug           : false,
18536
  verbose         : false,
18537
  performance     : true,
18538
18539
  auto            : false,      // uses pjax style endpoints fetching content from same url with remote-content headers
18540
  history         : false,      // use browser history
18541
  historyType     : 'hash',     // #/ or html5 state
18542
  path            : false,      // base path of url
18543
18544
  context         : false,      // specify a context that tabs must appear inside
18545
  childrenOnly    : false,      // use only tabs that are children of context
18546
  maxDepth        : 25,         // max depth a tab can be nested
18547
18548
  deactivate      : 'siblings', // whether tabs should deactivate sibling menu elements or all elements initialized together
18549
18550
  alwaysRefresh   : false,      // load tab content new every tab click
18551
  cache           : true,       // cache the content requests to pull locally
18552
  loadOnce        : false,      // Whether tab data should only be loaded once when using remote content
18553
  cacheType       : 'response', // Whether to cache exact response, or to html cache contents after scripts execute
18554
  ignoreFirstLoad : false,      // don't load remote content on first load
18555
18556
  apiSettings     : false,      // settings for api call
18557
  evaluateScripts : 'once',     // whether inline scripts should be parsed (true/false/once). Once will not re-evaluate on cached content
18558
18559
  onFirstLoad : function(tabPath, parameterArray, historyEvent) {}, // called first time loaded
0 ignored issues
show
Unused Code introduced by
The parameter parameterArray is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter tabPath is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter historyEvent is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
18560
  onLoad      : function(tabPath, parameterArray, historyEvent) {}, // called on every load
0 ignored issues
show
Unused Code introduced by
The parameter historyEvent is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter tabPath is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter parameterArray is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
18561
  onVisible   : function(tabPath, parameterArray, historyEvent) {}, // called every time tab visible
0 ignored issues
show
Unused Code introduced by
The parameter historyEvent is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter parameterArray is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter tabPath is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
18562
  onRequest   : function(tabPath, parameterArray, historyEvent) {}, // called ever time a tab beings loading remote content
0 ignored issues
show
Unused Code introduced by
The parameter tabPath is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter historyEvent is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter parameterArray is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
18563
18564
  templates : {
18565
    determineTitle: function(tabArray) {} // returns page title for path
0 ignored issues
show
Unused Code introduced by
The parameter tabArray is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
18566
  },
18567
18568
  error: {
18569
    api        : 'You attempted to load content without API module',
18570
    method     : 'The method you called is not defined',
18571
    missingTab : 'Activated tab cannot be found. Tabs are case-sensitive.',
18572
    noContent  : 'The tab you specified is missing a content url.',
18573
    path       : 'History enabled, but no path was specified',
18574
    recursion  : 'Max recursive depth reached',
18575
    legacyInit : 'onTabInit has been renamed to onFirstLoad in 2.0, please adjust your code.',
18576
    legacyLoad : 'onTabLoad has been renamed to onLoad in 2.0. Please adjust your code',
18577
    state      : 'History requires Asual\'s Address library <https://github.com/asual/jquery-address>'
18578
  },
18579
18580
  metadata : {
18581
    tab    : 'tab',
18582
    loaded : 'loaded',
18583
    promise: 'promise'
18584
  },
18585
18586
  className   : {
18587
    loading : 'loading',
18588
    active  : 'active'
18589
  },
18590
18591
  selector    : {
18592
    tabs : '.ui.tab',
18593
    ui   : '.ui'
18594
  }
18595
18596
};
18597
18598
})( jQuery, window, document );
18599
18600
/*!
18601
 * # Semantic UI 2.2.11 - Transition
18602
 * http://github.com/semantic-org/semantic-ui/
18603
 *
18604
 *
18605
 * Released under the MIT license
18606
 * http://opensource.org/licenses/MIT
18607
 *
18608
 */
18609
18610 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
18611
18612
"use strict";
18613
18614
window = (typeof window != 'undefined' && window.Math == Math)
18615
  ? window
18616
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
18617
    ? self
18618
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
18619
;
18620
18621
$.fn.transition = function() {
18622
  var
18623
    $allModules     = $(this),
18624
    moduleSelector  = $allModules.selector || '',
18625
18626
    time            = new Date().getTime(),
18627
    performance     = [],
18628
18629
    moduleArguments = arguments,
18630
    query           = moduleArguments[0],
18631
    queryArguments  = [].slice.call(arguments, 1),
18632
    methodInvoked   = (typeof query === 'string'),
18633
18634
    requestAnimationFrame = window.requestAnimationFrame
0 ignored issues
show
Unused Code introduced by
The assignment to variable requestAnimationFrame seems to be never used. Consider removing it.
Loading history...
18635
      || window.mozRequestAnimationFrame
18636
      || window.webkitRequestAnimationFrame
18637
      || window.msRequestAnimationFrame
18638
      || function(callback) { setTimeout(callback, 0); },
18639
18640
    returnedValue
18641
  ;
18642
  $allModules
18643
    .each(function(index) {
18644
      var
18645
        $module  = $(this),
18646
        element  = this,
18647
18648
        // set at run time
18649
        settings,
18650
        instance,
18651
18652
        error,
18653
        className,
18654
        metadata,
18655
        animationEnd,
18656
        animationName,
18657
18658
        namespace,
18659
        moduleNamespace,
18660
        eventNamespace,
18661
        module
18662
      ;
18663
18664
      module = {
18665
18666
        initialize: function() {
18667
18668
          // get full settings
18669
          settings        = module.get.settings.apply(element, moduleArguments);
18670
18671
          // shorthand
18672
          className       = settings.className;
18673
          error           = settings.error;
18674
          metadata        = settings.metadata;
18675
18676
          // define namespace
18677
          eventNamespace  = '.' + settings.namespace;
18678
          moduleNamespace = 'module-' + settings.namespace;
18679
          instance        = $module.data(moduleNamespace) || module;
18680
18681
          // get vendor specific events
18682
          animationEnd    = module.get.animationEndEvent();
0 ignored issues
show
Bug introduced by
The variable module seems to not be initialized for all possible execution paths.
Loading history...
18683
18684
          if(methodInvoked) {
18685
            methodInvoked = module.invoke(query);
18686
          }
18687
18688
          // method not invoked, lets run an animation
18689
          if(methodInvoked === false) {
18690
            module.verbose('Converted arguments into settings object', settings);
18691
            if(settings.interval) {
18692
              module.delay(settings.animate);
18693
            }
18694
            else  {
18695
              module.animate();
18696
            }
18697
            module.instantiate();
18698
          }
18699
        },
18700
18701
        instantiate: function() {
18702
          module.verbose('Storing instance of module', module);
18703
          instance = module;
18704
          $module
18705
            .data(moduleNamespace, instance)
18706
          ;
18707
        },
18708
18709
        destroy: function() {
18710
          module.verbose('Destroying previous module for', element);
18711
          $module
18712
            .removeData(moduleNamespace)
18713
          ;
18714
        },
18715
18716
        refresh: function() {
18717
          module.verbose('Refreshing display type on next animation');
18718
          delete module.displayType;
18719
        },
18720
18721
        forceRepaint: function() {
18722
          module.verbose('Forcing element repaint');
18723
          var
18724
            $parentElement = $module.parent(),
18725
            $nextElement = $module.next()
18726
          ;
18727
          if($nextElement.length === 0) {
18728
            $module.detach().appendTo($parentElement);
18729
          }
18730
          else {
18731
            $module.detach().insertBefore($nextElement);
18732
          }
18733
        },
18734
18735
        repaint: function() {
18736
          module.verbose('Repainting element');
18737
          var
18738
            fakeAssignment = element.offsetWidth
0 ignored issues
show
Unused Code introduced by
The variable fakeAssignment seems to be never used. Consider removing it.
Loading history...
18739
          ;
18740
        },
18741
18742
        delay: function(interval) {
18743
          var
18744
            direction = module.get.animationDirection(),
18745
            shouldReverse,
18746
            delay
18747
          ;
18748
          if(!direction) {
18749
            direction = module.can.transition()
18750
              ? module.get.direction()
18751
              : 'static'
18752
            ;
18753
          }
18754
          interval = (interval !== undefined)
18755
            ? interval
18756
            : settings.interval
18757
          ;
18758
          shouldReverse = (settings.reverse == 'auto' && direction == className.outward);
18759
          delay = (shouldReverse || settings.reverse == true)
0 ignored issues
show
Best Practice introduced by
Comparing settings.reverse to true using the == operator is not safe. Consider using === instead.
Loading history...
18760
            ? ($allModules.length - index) * settings.interval
18761
            : index * settings.interval
18762
          ;
18763
          module.debug('Delaying animation by', delay);
18764
          setTimeout(module.animate, delay);
18765
        },
18766
18767
        animate: function(overrideSettings) {
18768
          settings = overrideSettings || settings;
18769
          if(!module.is.supported()) {
18770
            module.error(error.support);
18771
            return false;
18772
          }
18773
          module.debug('Preparing animation', settings.animation);
18774
          if(module.is.animating()) {
18775
            if(settings.queue) {
18776
              if(!settings.allowRepeats && module.has.direction() && module.is.occurring() && module.queuing !== true) {
18777
                module.debug('Animation is currently occurring, preventing queueing same animation', settings.animation);
18778
              }
18779
              else {
18780
                module.queue(settings.animation);
18781
              }
18782
              return false;
18783
            }
18784
            else if(!settings.allowRepeats && module.is.occurring()) {
18785
              module.debug('Animation is already occurring, will not execute repeated animation', settings.animation);
18786
              return false;
18787
            }
18788
            else {
18789
              module.debug('New animation started, completing previous early', settings.animation);
18790
              instance.complete();
18791
            }
18792
          }
18793
          if( module.can.animate() ) {
18794
            module.set.animating(settings.animation);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
18795
          }
18796
          else {
18797
            module.error(error.noAnimation, settings.animation, element);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
18798
          }
18799
        },
18800
18801
        reset: function() {
18802
          module.debug('Resetting animation to beginning conditions');
18803
          module.remove.animationCallbacks();
18804
          module.restore.conditions();
18805
          module.remove.animating();
18806
        },
18807
18808
        queue: function(animation) {
18809
          module.debug('Queueing animation of', animation);
18810
          module.queuing = true;
18811
          $module
18812
            .one(animationEnd + '.queue' + eventNamespace, function() {
18813
              module.queuing = false;
18814
              module.repaint();
18815
              module.animate.apply(this, settings);
18816
            })
18817
          ;
18818
        },
18819
18820
        complete: function (event) {
0 ignored issues
show
Unused Code introduced by
The parameter event is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
18821
          module.debug('Animation complete', settings.animation);
18822
          module.remove.completeCallback();
18823
          module.remove.failSafe();
18824
          if(!module.is.looping()) {
18825
            if( module.is.outward() ) {
18826
              module.verbose('Animation is outward, hiding element');
18827
              module.restore.conditions();
18828
              module.hide();
18829
            }
18830
            else if( module.is.inward() ) {
18831
              module.verbose('Animation is outward, showing element');
18832
              module.restore.conditions();
18833
              module.show();
18834
            }
18835
            else {
18836
              module.verbose('Static animation completed');
18837
              module.restore.conditions();
18838
              settings.onComplete.call(element);
18839
            }
18840
          }
18841
        },
18842
18843
        force: {
18844
          visible: function() {
18845
            var
18846
              style          = $module.attr('style'),
18847
              userStyle      = module.get.userStyle(),
18848
              displayType    = module.get.displayType(),
18849
              overrideStyle  = userStyle + 'display: ' + displayType + ' !important;',
18850
              currentDisplay = $module.css('display'),
18851
              emptyStyle     = (style === undefined || style === '')
18852
            ;
18853
            if(currentDisplay !== displayType) {
18854
              module.verbose('Overriding default display to show element', displayType);
18855
              $module
18856
                .attr('style', overrideStyle)
18857
              ;
18858
            }
18859
            else if(emptyStyle) {
18860
              $module.removeAttr('style');
18861
            }
18862
          },
18863
          hidden: function() {
18864
            var
18865
              style          = $module.attr('style'),
18866
              currentDisplay = $module.css('display'),
18867
              emptyStyle     = (style === undefined || style === '')
18868
            ;
18869
            if(currentDisplay !== 'none' && !module.is.hidden()) {
18870
              module.verbose('Overriding default display to hide element');
18871
              $module
18872
                .css('display', 'none')
18873
              ;
18874
            }
18875
            else if(emptyStyle) {
18876
              $module
18877
                .removeAttr('style')
18878
              ;
18879
            }
18880
          }
18881
        },
18882
18883
        has: {
18884
          direction: function(animation) {
18885
            var
18886
              hasDirection = false
18887
            ;
18888
            animation = animation || settings.animation;
18889
            if(typeof animation === 'string') {
18890
              animation = animation.split(' ');
18891
              $.each(animation, function(index, word){
18892
                if(word === className.inward || word === className.outward) {
18893
                  hasDirection = true;
18894
                }
18895
              });
18896
            }
18897
            return hasDirection;
18898
          },
18899
          inlineDisplay: function() {
18900
            var
18901
              style = $module.attr('style') || ''
18902
            ;
18903
            return $.isArray(style.match(/display.*?;/, ''));
18904
          }
18905
        },
18906
18907
        set: {
18908
          animating: function(animation) {
18909
            var
18910
              animationClass,
18911
              direction
18912
            ;
18913
            // remove previous callbacks
18914
            module.remove.completeCallback();
18915
18916
            // determine exact animation
18917
            animation      = animation || settings.animation;
18918
            animationClass = module.get.animationClass(animation);
18919
18920
            // save animation class in cache to restore class names
18921
            module.save.animation(animationClass);
18922
18923
            // override display if necessary so animation appears visibly
18924
            module.force.visible();
18925
18926
            module.remove.hidden();
18927
            module.remove.direction();
18928
18929
            module.start.animation(animationClass);
18930
18931
          },
18932
          duration: function(animationName, duration) {
18933
            duration = duration || settings.duration;
18934
            duration = (typeof duration == 'number')
18935
              ? duration + 'ms'
18936
              : duration
18937
            ;
18938
            if(duration || duration === 0) {
18939
              module.verbose('Setting animation duration', duration);
18940
              $module
18941
                .css({
18942
                  'animation-duration':  duration
18943
                })
18944
              ;
18945
            }
18946
          },
18947
          direction: function(direction) {
18948
            direction = direction || module.get.direction();
18949
            if(direction == className.inward) {
18950
              module.set.inward();
18951
            }
18952
            else {
18953
              module.set.outward();
18954
            }
18955
          },
18956
          looping: function() {
18957
            module.debug('Transition set to loop');
18958
            $module
18959
              .addClass(className.looping)
18960
            ;
18961
          },
18962
          hidden: function() {
18963
            $module
18964
              .addClass(className.transition)
18965
              .addClass(className.hidden)
18966
            ;
18967
          },
18968
          inward: function() {
18969
            module.debug('Setting direction to inward');
18970
            $module
18971
              .removeClass(className.outward)
18972
              .addClass(className.inward)
18973
            ;
18974
          },
18975
          outward: function() {
18976
            module.debug('Setting direction to outward');
18977
            $module
18978
              .removeClass(className.inward)
18979
              .addClass(className.outward)
18980
            ;
18981
          },
18982
          visible: function() {
18983
            $module
18984
              .addClass(className.transition)
18985
              .addClass(className.visible)
18986
            ;
18987
          }
18988
        },
18989
18990
        start: {
18991
          animation: function(animationClass) {
18992
            animationClass = animationClass || module.get.animationClass();
18993
            module.debug('Starting tween', animationClass);
18994
            $module
18995
              .addClass(animationClass)
18996
              .one(animationEnd + '.complete' + eventNamespace, module.complete)
18997
            ;
18998
            if(settings.useFailSafe) {
18999
              module.add.failSafe();
19000
            }
19001
            module.set.duration(settings.duration);
19002
            settings.onStart.call(element);
19003
          }
19004
        },
19005
19006
        save: {
19007
          animation: function(animation) {
19008
            if(!module.cache) {
19009
              module.cache = {};
19010
            }
19011
            module.cache.animation = animation;
19012
          },
19013
          displayType: function(displayType) {
19014
            if(displayType !== 'none') {
19015
              $module.data(metadata.displayType, displayType);
19016
            }
19017
          },
19018
          transitionExists: function(animation, exists) {
19019
            $.fn.transition.exists[animation] = exists;
19020
            module.verbose('Saving existence of transition', animation, exists);
19021
          }
19022
        },
19023
19024
        restore: {
19025
          conditions: function() {
19026
            var
19027
              animation = module.get.currentAnimation()
19028
            ;
19029
            if(animation) {
19030
              $module
19031
                .removeClass(animation)
19032
              ;
19033
              module.verbose('Removing animation class', module.cache);
19034
            }
19035
            module.remove.duration();
19036
          }
19037
        },
19038
19039
        add: {
19040
          failSafe: function() {
19041
            var
19042
              duration = module.get.duration()
19043
            ;
19044
            module.timer = setTimeout(function() {
19045
              $module.triggerHandler(animationEnd);
19046
            }, duration + settings.failSafeDelay);
19047
            module.verbose('Adding fail safe timer', module.timer);
19048
          }
19049
        },
19050
19051
        remove: {
19052
          animating: function() {
19053
            $module.removeClass(className.animating);
19054
          },
19055
          animationCallbacks: function() {
19056
            module.remove.queueCallback();
19057
            module.remove.completeCallback();
19058
          },
19059
          queueCallback: function() {
19060
            $module.off('.queue' + eventNamespace);
19061
          },
19062
          completeCallback: function() {
19063
            $module.off('.complete' + eventNamespace);
19064
          },
19065
          display: function() {
19066
            $module.css('display', '');
19067
          },
19068
          direction: function() {
19069
            $module
19070
              .removeClass(className.inward)
19071
              .removeClass(className.outward)
19072
            ;
19073
          },
19074
          duration: function() {
19075
            $module
19076
              .css('animation-duration', '')
19077
            ;
19078
          },
19079
          failSafe: function() {
19080
            module.verbose('Removing fail safe timer', module.timer);
19081
            if(module.timer) {
19082
              clearTimeout(module.timer);
19083
            }
19084
          },
19085
          hidden: function() {
19086
            $module.removeClass(className.hidden);
19087
          },
19088
          visible: function() {
19089
            $module.removeClass(className.visible);
19090
          },
19091
          looping: function() {
19092
            module.debug('Transitions are no longer looping');
19093
            if( module.is.looping() ) {
19094
              module.reset();
19095
              $module
19096
                .removeClass(className.looping)
19097
              ;
19098
            }
19099
          },
19100
          transition: function() {
19101
            $module
19102
              .removeClass(className.visible)
19103
              .removeClass(className.hidden)
19104
            ;
19105
          }
19106
        },
19107
        get: {
19108
          settings: function(animation, duration, onComplete) {
19109
            // single settings object
19110
            if(typeof animation == 'object') {
19111
              return $.extend(true, {}, $.fn.transition.settings, animation);
19112
            }
19113
            // all arguments provided
19114
            else if(typeof onComplete == 'function') {
19115
              return $.extend({}, $.fn.transition.settings, {
19116
                animation  : animation,
19117
                onComplete : onComplete,
19118
                duration   : duration
19119
              });
19120
            }
19121
            // only duration provided
19122
            else if(typeof duration == 'string' || typeof duration == 'number') {
19123
              return $.extend({}, $.fn.transition.settings, {
19124
                animation : animation,
19125
                duration  : duration
19126
              });
19127
            }
19128
            // duration is actually settings object
19129
            else if(typeof duration == 'object') {
19130
              return $.extend({}, $.fn.transition.settings, duration, {
19131
                animation : animation
19132
              });
19133
            }
19134
            // duration is actually callback
19135
            else if(typeof duration == 'function') {
19136
              return $.extend({}, $.fn.transition.settings, {
19137
                animation  : animation,
19138
                onComplete : duration
19139
              });
19140
            }
19141
            // only animation provided
19142
            else {
19143
              return $.extend({}, $.fn.transition.settings, {
19144
                animation : animation
19145
              });
19146
            }
19147
          },
19148
          animationClass: function(animation) {
19149
            var
19150
              animationClass = animation || settings.animation,
19151
              directionClass = (module.can.transition() && !module.has.direction())
19152
                ? module.get.direction() + ' '
19153
                : ''
19154
            ;
19155
            return className.animating + ' '
19156
              + className.transition + ' '
19157
              + directionClass
19158
              + animationClass
19159
            ;
19160
          },
19161
          currentAnimation: function() {
19162
            return (module.cache && module.cache.animation !== undefined)
19163
              ? module.cache.animation
19164
              : false
19165
            ;
19166
          },
19167
          currentDirection: function() {
19168
            return module.is.inward()
19169
              ? className.inward
19170
              : className.outward
19171
            ;
19172
          },
19173
          direction: function() {
19174
            return module.is.hidden() || !module.is.visible()
19175
              ? className.inward
19176
              : className.outward
19177
            ;
19178
          },
19179
          animationDirection: function(animation) {
19180
            var
19181
              direction
19182
            ;
19183
            animation = animation || settings.animation;
19184
            if(typeof animation === 'string') {
19185
              animation = animation.split(' ');
19186
              // search animation name for out/in class
19187
              $.each(animation, function(index, word){
19188
                if(word === className.inward) {
19189
                  direction = className.inward;
19190
                }
19191
                else if(word === className.outward) {
19192
                  direction = className.outward;
19193
                }
19194
              });
19195
            }
19196
            // return found direction
19197
            if(direction) {
19198
              return direction;
19199
            }
19200
            return false;
19201
          },
19202
          duration: function(duration) {
19203
            duration = duration || settings.duration;
19204
            if(duration === false) {
19205
              duration = $module.css('animation-duration') || 0;
19206
            }
19207
            return (typeof duration === 'string')
19208
              ? (duration.indexOf('ms') > -1)
19209
                ? parseFloat(duration)
19210
                : parseFloat(duration) * 1000
19211
              : duration
19212
            ;
19213
          },
19214
          displayType: function(shouldDetermine) {
19215
            shouldDetermine = (shouldDetermine !== undefined)
19216
              ? shouldDetermine
19217
              : true
19218
            ;
19219
            if(settings.displayType) {
19220
              return settings.displayType;
19221
            }
19222
            if(shouldDetermine && $module.data(metadata.displayType) === undefined) {
19223
              // create fake element to determine display state
19224
              module.can.transition(true);
19225
            }
19226
            return $module.data(metadata.displayType);
19227
          },
19228
          userStyle: function(style) {
19229
            style = style || $module.attr('style') || '';
19230
            return style.replace(/display.*?;/, '');
19231
          },
19232
          transitionExists: function(animation) {
19233
            return $.fn.transition.exists[animation];
19234
          },
19235
          animationStartEvent: function() {
19236
            var
19237
              element     = document.createElement('div'),
19238
              animations  = {
19239
                'animation'       :'animationstart',
19240
                'OAnimation'      :'oAnimationStart',
19241
                'MozAnimation'    :'mozAnimationStart',
19242
                'WebkitAnimation' :'webkitAnimationStart'
19243
              },
19244
              animation
19245
            ;
19246
            for(animation in animations){
19247
              if( element.style[animation] !== undefined ){
19248
                return animations[animation];
19249
              }
19250
            }
19251
            return false;
19252
          },
19253
          animationEndEvent: function() {
19254
            var
19255
              element     = document.createElement('div'),
19256
              animations  = {
19257
                'animation'       :'animationend',
19258
                'OAnimation'      :'oAnimationEnd',
19259
                'MozAnimation'    :'mozAnimationEnd',
19260
                'WebkitAnimation' :'webkitAnimationEnd'
19261
              },
19262
              animation
19263
            ;
19264
            for(animation in animations){
19265
              if( element.style[animation] !== undefined ){
19266
                return animations[animation];
19267
              }
19268
            }
19269
            return false;
19270
          }
19271
19272
        },
19273
19274
        can: {
19275
          transition: function(forced) {
19276
            var
19277
              animation         = settings.animation,
19278
              transitionExists  = module.get.transitionExists(animation),
19279
              displayType       = module.get.displayType(false),
19280
              elementClass,
19281
              tagName,
19282
              $clone,
19283
              currentAnimation,
19284
              inAnimation,
19285
              directionExists
19286
            ;
19287
            if( transitionExists === undefined || forced) {
19288
              module.verbose('Determining whether animation exists');
19289
              elementClass = $module.attr('class');
19290
              tagName      = $module.prop('tagName');
19291
19292
              $clone = $('<' + tagName + ' />').addClass( elementClass ).insertAfter($module);
19293
              currentAnimation = $clone
19294
                .addClass(animation)
19295
                .removeClass(className.inward)
19296
                .removeClass(className.outward)
19297
                .addClass(className.animating)
19298
                .addClass(className.transition)
19299
                .css('animationName')
19300
              ;
19301
              inAnimation = $clone
19302
                .addClass(className.inward)
19303
                .css('animationName')
19304
              ;
19305
              if(!displayType) {
19306
                displayType = $clone
19307
                  .attr('class', elementClass)
19308
                  .removeAttr('style')
19309
                  .removeClass(className.hidden)
19310
                  .removeClass(className.visible)
19311
                  .show()
19312
                  .css('display')
19313
                ;
19314
                module.verbose('Determining final display state', displayType);
19315
                module.save.displayType(displayType);
19316
              }
19317
19318
              $clone.remove();
19319
              if(currentAnimation != inAnimation) {
19320
                module.debug('Direction exists for animation', animation);
19321
                directionExists = true;
19322
              }
19323
              else if(currentAnimation == 'none' || !currentAnimation) {
19324
                module.debug('No animation defined in css', animation);
19325
                return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
19326
              }
19327
              else {
19328
                module.debug('Static animation found', animation, displayType);
19329
                directionExists = false;
19330
              }
19331
              module.save.transitionExists(animation, directionExists);
19332
            }
19333
            return (transitionExists !== undefined)
19334
              ? transitionExists
19335
              : directionExists
0 ignored issues
show
Bug introduced by
The variable directionExists does not seem to be initialized in case transitionExists === undefined || forced on line 19287 is false. Are you sure this can never be the case?
Loading history...
19336
            ;
19337
          },
19338
          animate: function() {
19339
            // can transition does not return a value if animation does not exist
19340
            return (module.can.transition() !== undefined);
19341
          }
19342
        },
19343
19344
        is: {
19345
          animating: function() {
19346
            return $module.hasClass(className.animating);
19347
          },
19348
          inward: function() {
19349
            return $module.hasClass(className.inward);
19350
          },
19351
          outward: function() {
19352
            return $module.hasClass(className.outward);
19353
          },
19354
          looping: function() {
19355
            return $module.hasClass(className.looping);
19356
          },
19357
          occurring: function(animation) {
19358
            animation = animation || settings.animation;
19359
            animation = '.' + animation.replace(' ', '.');
19360
            return ( $module.filter(animation).length > 0 );
19361
          },
19362
          visible: function() {
19363
            return $module.is(':visible');
19364
          },
19365
          hidden: function() {
19366
            return $module.css('visibility') === 'hidden';
19367
          },
19368
          supported: function() {
19369
            return(animationEnd !== false);
19370
          }
19371
        },
19372
19373
        hide: function() {
19374
          module.verbose('Hiding element');
19375
          if( module.is.animating() ) {
19376
            module.reset();
19377
          }
19378
          element.blur(); // IE will trigger focus change if element is not blurred before hiding
19379
          module.remove.display();
19380
          module.remove.visible();
19381
          module.set.hidden();
19382
          module.force.hidden();
19383
          settings.onHide.call(element);
19384
          settings.onComplete.call(element);
19385
          // module.repaint();
19386
        },
19387
19388
        show: function(display) {
19389
          module.verbose('Showing element', display);
19390
          module.remove.hidden();
19391
          module.set.visible();
19392
          module.force.visible();
19393
          settings.onShow.call(element);
19394
          settings.onComplete.call(element);
19395
          // module.repaint();
19396
        },
19397
19398
        toggle: function() {
19399
          if( module.is.visible() ) {
19400
            module.hide();
19401
          }
19402
          else {
19403
            module.show();
19404
          }
19405
        },
19406
19407
        stop: function() {
19408
          module.debug('Stopping current animation');
19409
          $module.triggerHandler(animationEnd);
19410
        },
19411
19412
        stopAll: function() {
19413
          module.debug('Stopping all animation');
19414
          module.remove.queueCallback();
19415
          $module.triggerHandler(animationEnd);
19416
        },
19417
19418
        clear: {
19419
          queue: function() {
19420
            module.debug('Clearing animation queue');
19421
            module.remove.queueCallback();
19422
          }
19423
        },
19424
19425
        enable: function() {
19426
          module.verbose('Starting animation');
19427
          $module.removeClass(className.disabled);
19428
        },
19429
19430
        disable: function() {
19431
          module.debug('Stopping animation');
19432
          $module.addClass(className.disabled);
19433
        },
19434
19435
        setting: function(name, value) {
19436
          module.debug('Changing setting', name, value);
19437
          if( $.isPlainObject(name) ) {
19438
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
19439
          }
19440
          else if(value !== undefined) {
19441
            if($.isPlainObject(settings[name])) {
19442
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
19443
            }
19444
            else {
19445
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
19446
            }
19447
          }
19448
          else {
19449
            return settings[name];
19450
          }
19451
        },
19452
        internal: function(name, value) {
19453
          if( $.isPlainObject(name) ) {
19454
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
19455
          }
19456
          else if(value !== undefined) {
19457
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
19458
          }
19459
          else {
19460
            return module[name];
19461
          }
19462
        },
19463
        debug: function() {
19464
          if(!settings.silent && settings.debug) {
19465
            if(settings.performance) {
19466
              module.performance.log(arguments);
19467
            }
19468
            else {
19469
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
19470
              module.debug.apply(console, arguments);
19471
            }
19472
          }
19473
        },
19474
        verbose: function() {
19475
          if(!settings.silent && settings.verbose && settings.debug) {
19476
            if(settings.performance) {
19477
              module.performance.log(arguments);
19478
            }
19479
            else {
19480
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
19481
              module.verbose.apply(console, arguments);
19482
            }
19483
          }
19484
        },
19485
        error: function() {
19486
          if(!settings.silent) {
19487
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
19488
            module.error.apply(console, arguments);
19489
          }
19490
        },
19491
        performance: {
19492
          log: function(message) {
19493
            var
19494
              currentTime,
19495
              executionTime,
19496
              previousTime
19497
            ;
19498
            if(settings.performance) {
19499
              currentTime   = new Date().getTime();
19500
              previousTime  = time || currentTime;
19501
              executionTime = currentTime - previousTime;
19502
              time          = currentTime;
19503
              performance.push({
19504
                'Name'           : message[0],
19505
                'Arguments'      : [].slice.call(message, 1) || '',
19506
                'Element'        : element,
19507
                'Execution Time' : executionTime
19508
              });
19509
            }
19510
            clearTimeout(module.performance.timer);
19511
            module.performance.timer = setTimeout(module.performance.display, 500);
19512
          },
19513
          display: function() {
19514
            var
19515
              title = settings.name + ':',
19516
              totalTime = 0
19517
            ;
19518
            time = false;
19519
            clearTimeout(module.performance.timer);
19520
            $.each(performance, function(index, data) {
19521
              totalTime += data['Execution Time'];
19522
            });
19523
            title += ' ' + totalTime + 'ms';
19524
            if(moduleSelector) {
19525
              title += ' \'' + moduleSelector + '\'';
19526
            }
19527
            if($allModules.length > 1) {
19528
              title += ' ' + '(' + $allModules.length + ')';
19529
            }
19530
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
19531
              console.groupCollapsed(title);
19532
              if(console.table) {
19533
                console.table(performance);
19534
              }
19535
              else {
19536
                $.each(performance, function(index, data) {
19537
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
19538
                });
19539
              }
19540
              console.groupEnd();
19541
            }
19542
            performance = [];
19543
          }
19544
        },
19545
        // modified for transition to return invoke success
19546
        invoke: function(query, passedArguments, context) {
19547
          var
19548
            object = instance,
19549
            maxDepth,
19550
            found,
19551
            response
19552
          ;
19553
          passedArguments = passedArguments || queryArguments;
19554
          context         = element         || context;
19555
          if(typeof query == 'string' && object !== undefined) {
19556
            query    = query.split(/[\. ]/);
19557
            maxDepth = query.length - 1;
19558
            $.each(query, function(depth, value) {
19559
              var camelCaseValue = (depth != maxDepth)
19560
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
19561
                : query
19562
              ;
19563
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
19564
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
19565
              }
19566
              else if( object[camelCaseValue] !== undefined ) {
19567
                found = object[camelCaseValue];
19568
                return false;
19569
              }
19570
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
19571
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
19572
              }
19573
              else if( object[value] !== undefined ) {
19574
                found = object[value];
19575
                return false;
19576
              }
19577
              else {
19578
                return false;
19579
              }
19580
            });
19581
          }
19582
          if ( $.isFunction( found ) ) {
19583
            response = found.apply(context, passedArguments);
19584
          }
19585
          else if(found !== undefined) {
19586
            response = found;
19587
          }
19588
19589
          if($.isArray(returnedValue)) {
19590
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 19585 is false. Are you sure the function push handles undefined variables?
Loading history...
19591
          }
19592
          else if(returnedValue !== undefined) {
19593
            returnedValue = [returnedValue, response];
19594
          }
19595
          else if(response !== undefined) {
19596
            returnedValue = response;
19597
          }
19598
          return (found !== undefined)
19599
            ? found
19600
            : false
19601
          ;
19602
        }
19603
      };
19604
      module.initialize();
19605
    })
19606
  ;
19607
  return (returnedValue !== undefined)
19608
    ? returnedValue
19609
    : this
19610
  ;
19611
};
19612
19613
// Records if CSS transition is available
19614
$.fn.transition.exists = {};
19615
19616
$.fn.transition.settings = {
19617
19618
  // module info
19619
  name          : 'Transition',
19620
19621
  // hide all output from this component regardless of other settings
19622
  silent        : false,
19623
19624
  // debug content outputted to console
19625
  debug         : false,
19626
19627
  // verbose debug output
19628
  verbose       : false,
19629
19630
  // performance data output
19631
  performance   : true,
19632
19633
  // event namespace
19634
  namespace     : 'transition',
19635
19636
  // delay between animations in group
19637
  interval      : 0,
19638
19639
  // whether group animations should be reversed
19640
  reverse       : 'auto',
19641
19642
  // animation callback event
19643
  onStart       : function() {},
19644
  onComplete    : function() {},
19645
  onShow        : function() {},
19646
  onHide        : function() {},
19647
19648
  // whether timeout should be used to ensure callback fires in cases animationend does not
19649
  useFailSafe   : true,
19650
19651
  // delay in ms for fail safe
19652
  failSafeDelay : 100,
19653
19654
  // whether EXACT animation can occur twice in a row
19655
  allowRepeats  : false,
19656
19657
  // Override final display type on visible
19658
  displayType   : false,
19659
19660
  // animation duration
19661
  animation     : 'fade',
19662
  duration      : false,
19663
19664
  // new animations will occur after previous ones
19665
  queue         : true,
19666
19667
  metadata : {
19668
    displayType: 'display'
19669
  },
19670
19671
  className   : {
19672
    animating  : 'animating',
19673
    disabled   : 'disabled',
19674
    hidden     : 'hidden',
19675
    inward     : 'in',
19676
    loading    : 'loading',
19677
    looping    : 'looping',
19678
    outward    : 'out',
19679
    transition : 'transition',
19680
    visible    : 'visible'
19681
  },
19682
19683
  // possible errors
19684
  error: {
19685
    noAnimation : 'Element is no longer attached to DOM. Unable to animate.  Use silent setting to surpress this warning in production.',
19686
    repeated    : 'That animation is already occurring, cancelling repeated animation',
19687
    method      : 'The method you called is not defined',
19688
    support     : 'This browser does not support CSS animations'
19689
  }
19690
19691
};
19692
19693
19694
})( jQuery, window, document );
19695
19696
/*!
19697
 * # Semantic UI 2.2.11 - API
19698
 * http://github.com/semantic-org/semantic-ui/
19699
 *
19700
 *
19701
 * Released under the MIT license
19702
 * http://opensource.org/licenses/MIT
19703
 *
19704
 */
19705
19706 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
19707
19708
"use strict";
19709
19710
var
19711
  window = (typeof window != 'undefined' && window.Math == Math)
19712
    ? window
19713
    : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
19714
      ? self
19715
      : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
19716
;
19717
19718
$.api = $.fn.api = function(parameters) {
19719
19720
  var
19721
    // use window context if none specified
19722
    $allModules     = $.isFunction(this)
19723
        ? $(window)
19724
        : $(this),
19725
    moduleSelector = $allModules.selector || '',
19726
    time           = new Date().getTime(),
19727
    performance    = [],
19728
19729
    query          = arguments[0],
19730
    methodInvoked  = (typeof query == 'string'),
19731
    queryArguments = [].slice.call(arguments, 1),
19732
19733
    returnedValue
19734
  ;
19735
19736
  $allModules
19737
    .each(function() {
19738
      var
19739
        settings          = ( $.isPlainObject(parameters) )
19740
          ? $.extend(true, {}, $.fn.api.settings, parameters)
19741
          : $.extend({}, $.fn.api.settings),
19742
19743
        // internal aliases
19744
        namespace       = settings.namespace,
19745
        metadata        = settings.metadata,
19746
        selector        = settings.selector,
19747
        error           = settings.error,
19748
        className       = settings.className,
19749
19750
        // define namespaces for modules
19751
        eventNamespace  = '.' + namespace,
19752
        moduleNamespace = 'module-' + namespace,
19753
19754
        // element that creates request
19755
        $module         = $(this),
19756
        $form           = $module.closest(selector.form),
19757
19758
        // context used for state
19759
        $context        = (settings.stateContext)
19760
          ? $(settings.stateContext)
19761
          : $module,
19762
19763
        // request details
19764
        ajaxSettings,
19765
        requestSettings,
19766
        url,
19767
        data,
19768
        requestStartTime,
19769
19770
        // standard module
19771
        element         = this,
19772
        context         = $context[0],
19773
        instance        = $module.data(moduleNamespace),
19774
        module
19775
      ;
19776
19777
      module = {
19778
19779
        initialize: function() {
19780
          if(!methodInvoked) {
19781
            module.bind.events();
19782
          }
19783
          module.instantiate();
19784
        },
19785
19786
        instantiate: function() {
19787
          module.verbose('Storing instance of module', module);
19788
          instance = module;
19789
          $module
19790
            .data(moduleNamespace, instance)
19791
          ;
19792
        },
19793
19794
        destroy: function() {
19795
          module.verbose('Destroying previous module for', element);
19796
          $module
19797
            .removeData(moduleNamespace)
19798
            .off(eventNamespace)
19799
          ;
19800
        },
19801
19802
        bind: {
19803
          events: function() {
19804
            var
19805
              triggerEvent = module.get.event()
19806
            ;
19807
            if( triggerEvent ) {
19808
              module.verbose('Attaching API events to element', triggerEvent);
19809
              $module
19810
                .on(triggerEvent + eventNamespace, module.event.trigger)
19811
              ;
19812
            }
19813
            else if(settings.on == 'now') {
19814
              module.debug('Querying API endpoint immediately');
19815
              module.query();
19816
            }
19817
          }
19818
        },
19819
19820
        decode: {
19821
          json: function(response) {
19822
            if(response !== undefined && typeof response == 'string') {
19823
              try {
19824
               response = JSON.parse(response);
19825
              }
19826
              catch(e) {
0 ignored issues
show
Coding Style Comprehensibility Best Practice introduced by
Empty catch clauses should be used with caution; consider adding a comment why this is needed.
Loading history...
19827
                // isnt json string
19828
              }
19829
            }
19830
            return response;
19831
          }
19832
        },
19833
19834
        read: {
19835
          cachedResponse: function(url) {
19836
            var
19837
              response
19838
            ;
19839
            if(window.Storage === undefined) {
19840
              module.error(error.noStorage);
19841
              return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
19842
            }
19843
            response = sessionStorage.getItem(url);
0 ignored issues
show
Bug introduced by
The variable sessionStorage seems to be never declared. If this is a global, consider adding a /** global: sessionStorage */ 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...
19844
            module.debug('Using cached response', url, response);
19845
            response = module.decode.json(response);
19846
            return response;
19847
          }
19848
        },
19849
        write: {
19850
          cachedResponse: function(url, response) {
19851
            if(response && response === '') {
19852
              module.debug('Response empty, not caching', response);
19853
              return;
19854
            }
19855
            if(window.Storage === undefined) {
19856
              module.error(error.noStorage);
19857
              return;
19858
            }
19859
            if( $.isPlainObject(response) ) {
19860
              response = JSON.stringify(response);
19861
            }
19862
            sessionStorage.setItem(url, response);
0 ignored issues
show
Bug introduced by
The variable sessionStorage seems to be never declared. If this is a global, consider adding a /** global: sessionStorage */ 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...
19863
            module.verbose('Storing cached response for url', url, response);
19864
          }
19865
        },
19866
19867
        query: function() {
19868
19869
          if(module.is.disabled()) {
19870
            module.debug('Element is disabled API request aborted');
19871
            return;
19872
          }
19873
19874
          if(module.is.loading()) {
19875
            if(settings.interruptRequests) {
19876
              module.debug('Interrupting previous request');
19877
              module.abort();
19878
            }
19879
            else {
19880
              module.debug('Cancelling request, previous request is still pending');
19881
              return;
19882
            }
19883
          }
19884
19885
          // pass element metadata to url (value, text)
19886
          if(settings.defaultData) {
19887
            $.extend(true, settings.urlData, module.get.defaultData());
19888
          }
19889
19890
          // Add form content
19891
          if(settings.serializeForm) {
19892
            settings.data = module.add.formData(settings.data);
19893
          }
19894
19895
          // call beforesend and get any settings changes
19896
          requestSettings = module.get.settings();
19897
19898
          // check if before send cancelled request
19899
          if(requestSettings === false) {
19900
            module.cancelled = true;
19901
            module.error(error.beforeSend);
19902
            return;
19903
          }
19904
          else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
19905
            module.cancelled = false;
19906
          }
19907
19908
          // get url
19909
          url = module.get.templatedURL();
19910
19911
          if(!url && !module.is.mocked()) {
19912
            module.error(error.missingURL);
19913
            return;
19914
          }
19915
19916
          // replace variables
19917
          url = module.add.urlData( url );
19918
          // missing url parameters
19919
          if( !url && !module.is.mocked()) {
19920
            return;
19921
          }
19922
19923
          requestSettings.url = settings.base + url;
19924
19925
          // look for jQuery ajax parameters in settings
19926
          ajaxSettings = $.extend(true, {}, settings, {
19927
            type       : settings.method || settings.type,
19928
            data       : data,
0 ignored issues
show
Bug introduced by
The variable data seems to be never initialized.
Loading history...
19929
            url        : settings.base + url,
19930
            beforeSend : settings.beforeXHR,
19931
            success    : function() {},
19932
            failure    : function() {},
19933
            complete   : function() {}
19934
          });
19935
19936
          module.debug('Querying URL', ajaxSettings.url);
19937
          module.verbose('Using AJAX settings', ajaxSettings);
19938
          if(settings.cache === 'local' && module.read.cachedResponse(url)) {
19939
            module.debug('Response returned from local cache');
19940
            module.request = module.create.request();
19941
            module.request.resolveWith(context, [ module.read.cachedResponse(url) ]);
19942
            return;
19943
          }
19944
19945
          if( !settings.throttle ) {
19946
            module.debug('Sending request', data, ajaxSettings.method);
19947
            module.send.request();
19948
          }
19949
          else {
19950
            if(!settings.throttleFirstRequest && !module.timer) {
19951
              module.debug('Sending request', data, ajaxSettings.method);
19952
              module.send.request();
19953
              module.timer = setTimeout(function(){}, settings.throttle);
19954
            }
19955
            else {
19956
              module.debug('Throttling request', settings.throttle);
19957
              clearTimeout(module.timer);
19958
              module.timer = setTimeout(function() {
19959
                if(module.timer) {
19960
                  delete module.timer;
19961
                }
19962
                module.debug('Sending throttled request', data, ajaxSettings.method);
0 ignored issues
show
Bug introduced by
The variable data seems to be never initialized.
Loading history...
19963
                module.send.request();
19964
              }, settings.throttle);
19965
            }
19966
          }
19967
19968
        },
19969
19970
        should: {
19971
          removeError: function() {
19972
            return ( settings.hideError === true || (settings.hideError === 'auto' && !module.is.form()) );
19973
          }
19974
        },
19975
19976
        is: {
19977
          disabled: function() {
19978
            return ($module.filter(selector.disabled).length > 0);
19979
          },
19980
          expectingJSON: function() {
19981
            return settings.dataType === 'json' || settings.dataType === 'jsonp';
19982
          },
19983
          form: function() {
19984
            return $module.is('form') || $context.is('form');
19985
          },
19986
          mocked: function() {
19987
            return (settings.mockResponse || settings.mockResponseAsync || settings.response || settings.responseAsync);
19988
          },
19989
          input: function() {
19990
            return $module.is('input');
19991
          },
19992
          loading: function() {
19993
            return (module.request)
19994
              ? (module.request.state() == 'pending')
19995
              : false
19996
            ;
19997
          },
19998
          abortedRequest: function(xhr) {
19999
            if(xhr && xhr.readyState !== undefined && xhr.readyState === 0) {
20000
              module.verbose('XHR request determined to be aborted');
20001
              return true;
20002
            }
20003
            else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
20004
              module.verbose('XHR request was not aborted');
20005
              return false;
20006
            }
20007
          },
20008
          validResponse: function(response) {
20009
            if( (!module.is.expectingJSON()) || !$.isFunction(settings.successTest) ) {
20010
              module.verbose('Response is not JSON, skipping validation', settings.successTest, response);
20011
              return true;
20012
            }
20013
            module.debug('Checking JSON returned success', settings.successTest, response);
20014
            if( settings.successTest(response) ) {
20015
              module.debug('Response passed success test', response);
20016
              return true;
20017
            }
20018
            else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
20019
              module.debug('Response failed success test', response);
20020
              return false;
20021
            }
20022
          }
20023
        },
20024
20025
        was: {
20026
          cancelled: function() {
20027
            return (module.cancelled || false);
20028
          },
20029
          succesful: function() {
20030
            return (module.request && module.request.state() == 'resolved');
20031
          },
20032
          failure: function() {
20033
            return (module.request && module.request.state() == 'rejected');
20034
          },
20035
          complete: function() {
20036
            return (module.request && (module.request.state() == 'resolved' || module.request.state() == 'rejected') );
20037
          }
20038
        },
20039
20040
        add: {
20041
          urlData: function(url, urlData) {
20042
            var
20043
              requiredVariables,
20044
              optionalVariables
20045
            ;
20046
            if(url) {
20047
              requiredVariables = url.match(settings.regExp.required);
20048
              optionalVariables = url.match(settings.regExp.optional);
20049
              urlData           = urlData || settings.urlData;
20050
              if(requiredVariables) {
20051
                module.debug('Looking for required URL variables', requiredVariables);
20052
                $.each(requiredVariables, function(index, templatedString) {
20053
                  var
20054
                    // allow legacy {$var} style
20055
                    variable = (templatedString.indexOf('$') !== -1)
20056
                      ? templatedString.substr(2, templatedString.length - 3)
20057
                      : templatedString.substr(1, templatedString.length - 2),
20058
                    value   = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
20059
                      ? urlData[variable]
20060
                      : ($module.data(variable) !== undefined)
20061
                        ? $module.data(variable)
20062
                        : ($context.data(variable) !== undefined)
20063
                          ? $context.data(variable)
20064
                          : urlData[variable]
20065
                  ;
20066
                  // remove value
20067
                  if(value === undefined) {
20068
                    module.error(error.requiredParameter, variable, url);
20069
                    url = false;
20070
                    return false;
20071
                  }
20072
                  else {
0 ignored issues
show
Comprehensibility introduced by
else is not necessary here since all if branches return, consider removing it to reduce nesting and make code more readable.
Loading history...
20073
                    module.verbose('Found required variable', variable, value);
20074
                    value = (settings.encodeParameters)
20075
                      ? module.get.urlEncodedValue(value)
20076
                      : value
20077
                    ;
20078
                    url = url.replace(templatedString, value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
20079
                  }
20080
                });
20081
              }
20082
              if(optionalVariables) {
20083
                module.debug('Looking for optional URL variables', requiredVariables);
20084
                $.each(optionalVariables, function(index, templatedString) {
20085
                  var
20086
                    // allow legacy {/$var} style
20087
                    variable = (templatedString.indexOf('$') !== -1)
20088
                      ? templatedString.substr(3, templatedString.length - 4)
20089
                      : templatedString.substr(2, templatedString.length - 3),
20090
                    value   = ($.isPlainObject(urlData) && urlData[variable] !== undefined)
20091
                      ? urlData[variable]
20092
                      : ($module.data(variable) !== undefined)
20093
                        ? $module.data(variable)
20094
                        : ($context.data(variable) !== undefined)
20095
                          ? $context.data(variable)
20096
                          : urlData[variable]
20097
                  ;
20098
                  // optional replacement
20099
                  if(value !== undefined) {
20100
                    module.verbose('Optional variable Found', variable, value);
20101
                    url = url.replace(templatedString, value);
20102
                  }
20103
                  else {
20104
                    module.verbose('Optional variable not found', variable);
20105
                    // remove preceding slash if set
20106
                    if(url.indexOf('/' + templatedString) !== -1) {
20107
                      url = url.replace('/' + templatedString, '');
20108
                    }
20109
                    else {
20110
                      url = url.replace(templatedString, '');
20111
                    }
20112
                  }
20113
                });
20114
              }
20115
            }
20116
            return url;
20117
          },
20118
          formData: function(data) {
20119
            var
20120
              canSerialize = ($.fn.serializeObject !== undefined),
20121
              formData     = (canSerialize)
20122
                ? $form.serializeObject()
20123
                : $form.serialize(),
20124
              hasOtherData
20125
            ;
20126
            data         = data || settings.data;
20127
            hasOtherData = $.isPlainObject(data);
20128
20129
            if(hasOtherData) {
20130
              if(canSerialize) {
20131
                module.debug('Extending existing data with form data', data, formData);
20132
                data = $.extend(true, {}, data, formData);
20133
              }
20134
              else {
20135
                module.error(error.missingSerialize);
20136
                module.debug('Cant extend data. Replacing data with form data', data, formData);
20137
                data = formData;
20138
              }
20139
            }
20140
            else {
20141
              module.debug('Adding form data', formData);
20142
              data = formData;
20143
            }
20144
            return data;
20145
          }
20146
        },
20147
20148
        send: {
20149
          request: function() {
20150
            module.set.loading();
20151
            module.request = module.create.request();
20152
            if( module.is.mocked() ) {
20153
              module.mockedXHR = module.create.mockedXHR();
20154
            }
20155
            else {
20156
              module.xhr = module.create.xhr();
20157
            }
20158
            settings.onRequest.call(context, module.request, module.xhr);
20159
          }
20160
        },
20161
20162
        event: {
20163
          trigger: function(event) {
20164
            module.query();
20165
            if(event.type == 'submit' || event.type == 'click') {
20166
              event.preventDefault();
20167
            }
20168
          },
20169
          xhr: {
20170
            always: function() {
20171
              // nothing special
20172
            },
20173
            done: function(response, textStatus, xhr) {
20174
              var
20175
                context            = this,
20176
                elapsedTime        = (new Date().getTime() - requestStartTime),
20177
                timeLeft           = (settings.loadingDuration - elapsedTime),
20178
                translatedResponse = ( $.isFunction(settings.onResponse) )
20179
                  ? module.is.expectingJSON()
20180
                    ? settings.onResponse.call(context, $.extend(true, {}, response))
20181
                    : settings.onResponse.call(context, response)
20182
                  : false
20183
              ;
20184
              timeLeft = (timeLeft > 0)
20185
                ? timeLeft
20186
                : 0
20187
              ;
20188
              if(translatedResponse) {
20189
                module.debug('Modified API response in onResponse callback', settings.onResponse, translatedResponse, response);
20190
                response = translatedResponse;
20191
              }
20192
              if(timeLeft > 0) {
20193
                module.debug('Response completed early delaying state change by', timeLeft);
20194
              }
20195
              setTimeout(function() {
20196
                if( module.is.validResponse(response) ) {
20197
                  module.request.resolveWith(context, [response, xhr]);
20198
                }
20199
                else {
20200
                  module.request.rejectWith(context, [xhr, 'invalid']);
20201
                }
20202
              }, timeLeft);
20203
            },
20204
            fail: function(xhr, status, httpMessage) {
20205
              var
20206
                context     = this,
20207
                elapsedTime = (new Date().getTime() - requestStartTime),
20208
                timeLeft    = (settings.loadingDuration - elapsedTime)
20209
              ;
20210
              timeLeft = (timeLeft > 0)
20211
                ? timeLeft
20212
                : 0
20213
              ;
20214
              if(timeLeft > 0) {
20215
                module.debug('Response completed early delaying state change by', timeLeft);
20216
              }
20217
              setTimeout(function() {
20218
                if( module.is.abortedRequest(xhr) ) {
20219
                  module.request.rejectWith(context, [xhr, 'aborted', httpMessage]);
20220
                }
20221
                else {
20222
                  module.request.rejectWith(context, [xhr, 'error', status, httpMessage]);
20223
                }
20224
              }, timeLeft);
20225
            }
20226
          },
20227
          request: {
20228
            done: function(response, xhr) {
20229
              module.debug('Successful API Response', response);
20230
              if(settings.cache === 'local' && url) {
20231
                module.write.cachedResponse(url, response);
20232
                module.debug('Saving server response locally', module.cache);
20233
              }
20234
              settings.onSuccess.call(context, response, $module, xhr);
20235
            },
20236
            complete: function(firstParameter, secondParameter) {
20237
              var
20238
                xhr,
20239
                response
20240
              ;
20241
              // have to guess callback parameters based on request success
20242
              if( module.was.succesful() ) {
20243
                response = firstParameter;
20244
                xhr      = secondParameter;
20245
              }
20246
              else {
20247
                xhr      = firstParameter;
20248
                response = module.get.responseFromXHR(xhr);
20249
              }
20250
              module.remove.loading();
20251
              settings.onComplete.call(context, response, $module, xhr);
20252
            },
20253
            fail: function(xhr, status, httpMessage) {
20254
              var
20255
                // pull response from xhr if available
20256
                response     = module.get.responseFromXHR(xhr),
20257
                errorMessage = module.get.errorFromRequest(response, status, httpMessage)
20258
              ;
20259
              if(status == 'aborted') {
20260
                module.debug('XHR Aborted (Most likely caused by page navigation or CORS Policy)', status, httpMessage);
20261
                settings.onAbort.call(context, status, $module, xhr);
20262
                return true;
20263
              }
20264
              else if(status == 'invalid') {
20265
                module.debug('JSON did not pass success test. A server-side error has most likely occurred', response);
20266
              }
20267
              else if(status == 'error') {
20268
                if(xhr !== undefined) {
20269
                  module.debug('XHR produced a server error', status, httpMessage);
20270
                  // make sure we have an error to display to console
20271
                  if( xhr.status != 200 && httpMessage !== undefined && httpMessage !== '') {
20272
                    module.error(error.statusMessage + httpMessage, ajaxSettings.url);
20273
                  }
20274
                  settings.onError.call(context, errorMessage, $module, xhr);
20275
                }
20276
              }
20277
20278
              if(settings.errorDuration && status !== 'aborted') {
20279
                module.debug('Adding error state');
20280
                module.set.error();
20281
                if( module.should.removeError() ) {
20282
                  setTimeout(module.remove.error, settings.errorDuration);
20283
                }
20284
              }
20285
              module.debug('API Request failed', errorMessage, xhr);
20286
              settings.onFailure.call(context, response, $module, xhr);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
20287
            }
20288
          }
20289
        },
20290
20291
        create: {
20292
20293
          request: function() {
20294
            // api request promise
20295
            return $.Deferred()
20296
              .always(module.event.request.complete)
20297
              .done(module.event.request.done)
20298
              .fail(module.event.request.fail)
20299
            ;
20300
          },
20301
20302
          mockedXHR: function () {
20303
            var
20304
              // xhr does not simulate these properties of xhr but must return them
20305
              textStatus     = false,
20306
              status         = false,
20307
              httpMessage    = false,
20308
              responder      = settings.mockResponse      || settings.response,
20309
              asyncResponder = settings.mockResponseAsync || settings.responseAsync,
20310
              asyncCallback,
20311
              response,
20312
              mockedXHR
20313
            ;
20314
20315
            mockedXHR = $.Deferred()
20316
              .always(module.event.xhr.complete)
20317
              .done(module.event.xhr.done)
20318
              .fail(module.event.xhr.fail)
20319
            ;
20320
20321
            if(responder) {
20322
              if( $.isFunction(responder) ) {
20323
                module.debug('Using specified synchronous callback', responder);
20324
                response = responder.call(context, requestSettings);
20325
              }
20326
              else {
20327
                module.debug('Using settings specified response', responder);
20328
                response = responder;
20329
              }
20330
              // simulating response
20331
              mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
20332
            }
20333
            else if( $.isFunction(asyncResponder) ) {
20334
              asyncCallback = function(response) {
20335
                module.debug('Async callback returned response', response);
20336
20337
                if(response) {
20338
                  mockedXHR.resolveWith(context, [ response, textStatus, { responseText: response }]);
20339
                }
20340
                else {
20341
                  mockedXHR.rejectWith(context, [{ responseText: response }, status, httpMessage]);
20342
                }
20343
              };
20344
              module.debug('Using specified async response callback', asyncResponder);
20345
              asyncResponder.call(context, requestSettings, asyncCallback);
20346
            }
20347
            return mockedXHR;
20348
          },
20349
20350
          xhr: function() {
20351
            var
20352
              xhr
20353
            ;
20354
            // ajax request promise
20355
            xhr = $.ajax(ajaxSettings)
20356
              .always(module.event.xhr.always)
20357
              .done(module.event.xhr.done)
20358
              .fail(module.event.xhr.fail)
20359
            ;
20360
            module.verbose('Created server request', xhr, ajaxSettings);
20361
            return xhr;
20362
          }
20363
        },
20364
20365
        set: {
20366
          error: function() {
20367
            module.verbose('Adding error state to element', $context);
20368
            $context.addClass(className.error);
20369
          },
20370
          loading: function() {
20371
            module.verbose('Adding loading state to element', $context);
20372
            $context.addClass(className.loading);
20373
            requestStartTime = new Date().getTime();
20374
          }
20375
        },
20376
20377
        remove: {
20378
          error: function() {
20379
            module.verbose('Removing error state from element', $context);
20380
            $context.removeClass(className.error);
20381
          },
20382
          loading: function() {
20383
            module.verbose('Removing loading state from element', $context);
20384
            $context.removeClass(className.loading);
20385
          }
20386
        },
20387
20388
        get: {
20389
          responseFromXHR: function(xhr) {
20390
            return $.isPlainObject(xhr)
20391
              ? (module.is.expectingJSON())
20392
                ? module.decode.json(xhr.responseText)
20393
                : xhr.responseText
20394
              : false
20395
            ;
20396
          },
20397
          errorFromRequest: function(response, status, httpMessage) {
20398
            return ($.isPlainObject(response) && response.error !== undefined)
20399
              ? response.error // use json error message
20400
              : (settings.error[status] !== undefined) // use server error message
20401
                ? settings.error[status]
20402
                : httpMessage
20403
            ;
20404
          },
20405
          request: function() {
20406
            return module.request || false;
20407
          },
20408
          xhr: function() {
20409
            return module.xhr || false;
20410
          },
20411
          settings: function() {
20412
            var
20413
              runSettings
20414
            ;
20415
            runSettings = settings.beforeSend.call(context, settings);
20416
            if(runSettings) {
20417
              if(runSettings.success !== undefined) {
20418
                module.debug('Legacy success callback detected', runSettings);
20419
                module.error(error.legacyParameters, runSettings.success);
20420
                runSettings.onSuccess = runSettings.success;
20421
              }
20422
              if(runSettings.failure !== undefined) {
20423
                module.debug('Legacy failure callback detected', runSettings);
20424
                module.error(error.legacyParameters, runSettings.failure);
20425
                runSettings.onFailure = runSettings.failure;
20426
              }
20427
              if(runSettings.complete !== undefined) {
20428
                module.debug('Legacy complete callback detected', runSettings);
20429
                module.error(error.legacyParameters, runSettings.complete);
20430
                runSettings.onComplete = runSettings.complete;
20431
              }
20432
            }
20433
            if(runSettings === undefined) {
20434
              module.error(error.noReturnedValue);
20435
            }
20436
            if(runSettings === false) {
20437
              return runSettings;
20438
            }
20439
            return (runSettings !== undefined)
20440
              ? $.extend(true, {}, runSettings)
20441
              : $.extend(true, {}, settings)
20442
            ;
20443
          },
20444
          urlEncodedValue: function(value) {
20445
            var
20446
              decodedValue   = window.decodeURIComponent(value),
20447
              encodedValue   = window.encodeURIComponent(value),
20448
              alreadyEncoded = (decodedValue !== value)
20449
            ;
20450
            if(alreadyEncoded) {
20451
              module.debug('URL value is already encoded, avoiding double encoding', value);
20452
              return value;
20453
            }
20454
            module.verbose('Encoding value using encodeURIComponent', value, encodedValue);
20455
            return encodedValue;
20456
          },
20457
          defaultData: function() {
20458
            var
20459
              data = {}
20460
            ;
20461
            if( !$.isWindow(element) ) {
20462
              if( module.is.input() ) {
20463
                data.value = $module.val();
20464
              }
20465
              else if( module.is.form() ) {
0 ignored issues
show
Comprehensibility Documentation Best Practice introduced by
This code block is empty. Consider removing it or adding a comment to explain.
Loading history...
20466
20467
              }
20468
              else {
20469
                data.text = $module.text();
20470
              }
20471
            }
20472
            return data;
20473
          },
20474
          event: function() {
20475
            if( $.isWindow(element) || settings.on == 'now' ) {
20476
              module.debug('API called without element, no events attached');
20477
              return false;
20478
            }
20479
            else if(settings.on == 'auto') {
20480
              if( $module.is('input') ) {
20481
                return (element.oninput !== undefined)
20482
                  ? 'input'
20483
                  : (element.onpropertychange !== undefined)
20484
                    ? 'propertychange'
20485
                    : 'keyup'
20486
                ;
20487
              }
20488
              else if( $module.is('form') ) {
20489
                return 'submit';
20490
              }
20491
              else {
20492
                return 'click';
20493
              }
20494
            }
20495
            else {
20496
              return settings.on;
20497
            }
20498
          },
20499
          templatedURL: function(action) {
20500
            action = action || $module.data(metadata.action) || settings.action || false;
20501
            url    = $module.data(metadata.url) || settings.url || false;
20502
            if(url) {
20503
              module.debug('Using specified url', url);
20504
              return url;
20505
            }
20506
            if(action) {
20507
              module.debug('Looking up url for action', action, settings.api);
20508
              if(settings.api[action] === undefined && !module.is.mocked()) {
20509
                module.error(error.missingAction, settings.action, settings.api);
20510
                return;
0 ignored issues
show
Comprehensibility Best Practice introduced by
Are you sure this return statement is not missing an argument? If this is intended, consider adding an explicit undefined like return undefined;.
Loading history...
20511
              }
20512
              url = settings.api[action];
20513
            }
20514
            else if( module.is.form() ) {
20515
              url = $module.attr('action') || $context.attr('action') || false;
20516
              module.debug('No url or action specified, defaulting to form action', url);
20517
            }
20518
            return url;
20519
          }
20520
        },
20521
20522
        abort: function() {
20523
          var
20524
            xhr = module.get.xhr()
20525
          ;
20526
          if( xhr && xhr.state() !== 'resolved') {
20527
            module.debug('Cancelling API request');
20528
            xhr.abort();
20529
          }
20530
        },
20531
20532
        // reset state
20533
        reset: function() {
20534
          module.remove.error();
20535
          module.remove.loading();
20536
        },
20537
20538
        setting: function(name, value) {
20539
          module.debug('Changing setting', name, value);
20540
          if( $.isPlainObject(name) ) {
20541
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
20542
          }
20543
          else if(value !== undefined) {
20544
            if($.isPlainObject(settings[name])) {
20545
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
20546
            }
20547
            else {
20548
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
20549
            }
20550
          }
20551
          else {
20552
            return settings[name];
20553
          }
20554
        },
20555
        internal: function(name, value) {
20556
          if( $.isPlainObject(name) ) {
20557
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
20558
          }
20559
          else if(value !== undefined) {
20560
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
20561
          }
20562
          else {
20563
            return module[name];
20564
          }
20565
        },
20566
        debug: function() {
20567
          if(!settings.silent && settings.debug) {
20568
            if(settings.performance) {
20569
              module.performance.log(arguments);
20570
            }
20571
            else {
20572
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
20573
              module.debug.apply(console, arguments);
20574
            }
20575
          }
20576
        },
20577
        verbose: function() {
20578
          if(!settings.silent && settings.verbose && settings.debug) {
20579
            if(settings.performance) {
20580
              module.performance.log(arguments);
20581
            }
20582
            else {
20583
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
20584
              module.verbose.apply(console, arguments);
20585
            }
20586
          }
20587
        },
20588
        error: function() {
20589
          if(!settings.silent) {
20590
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
20591
            module.error.apply(console, arguments);
20592
          }
20593
        },
20594
        performance: {
20595
          log: function(message) {
20596
            var
20597
              currentTime,
20598
              executionTime,
20599
              previousTime
20600
            ;
20601
            if(settings.performance) {
20602
              currentTime   = new Date().getTime();
20603
              previousTime  = time || currentTime;
20604
              executionTime = currentTime - previousTime;
20605
              time          = currentTime;
20606
              performance.push({
20607
                'Name'           : message[0],
20608
                'Arguments'      : [].slice.call(message, 1) || '',
20609
                //'Element'        : element,
20610
                'Execution Time' : executionTime
20611
              });
20612
            }
20613
            clearTimeout(module.performance.timer);
20614
            module.performance.timer = setTimeout(module.performance.display, 500);
20615
          },
20616
          display: function() {
20617
            var
20618
              title = settings.name + ':',
20619
              totalTime = 0
20620
            ;
20621
            time = false;
20622
            clearTimeout(module.performance.timer);
20623
            $.each(performance, function(index, data) {
20624
              totalTime += data['Execution Time'];
20625
            });
20626
            title += ' ' + totalTime + 'ms';
20627
            if(moduleSelector) {
20628
              title += ' \'' + moduleSelector + '\'';
20629
            }
20630
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
20631
              console.groupCollapsed(title);
20632
              if(console.table) {
20633
                console.table(performance);
20634
              }
20635
              else {
20636
                $.each(performance, function(index, data) {
20637
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
20638
                });
20639
              }
20640
              console.groupEnd();
20641
            }
20642
            performance = [];
20643
          }
20644
        },
20645
        invoke: function(query, passedArguments, context) {
20646
          var
20647
            object = instance,
20648
            maxDepth,
20649
            found,
20650
            response
20651
          ;
20652
          passedArguments = passedArguments || queryArguments;
20653
          context         = element         || context;
20654
          if(typeof query == 'string' && object !== undefined) {
20655
            query    = query.split(/[\. ]/);
20656
            maxDepth = query.length - 1;
20657
            $.each(query, function(depth, value) {
20658
              var camelCaseValue = (depth != maxDepth)
20659
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
20660
                : query
20661
              ;
20662
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
20663
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
20664
              }
20665
              else if( object[camelCaseValue] !== undefined ) {
20666
                found = object[camelCaseValue];
20667
                return false;
20668
              }
20669
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
20670
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
20671
              }
20672
              else if( object[value] !== undefined ) {
20673
                found = object[value];
20674
                return false;
20675
              }
20676
              else {
20677
                module.error(error.method, query);
20678
                return false;
20679
              }
20680
            });
20681
          }
20682
          if ( $.isFunction( found ) ) {
20683
            response = found.apply(context, passedArguments);
20684
          }
20685
          else if(found !== undefined) {
20686
            response = found;
20687
          }
20688
          if($.isArray(returnedValue)) {
20689
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 20685 is false. Are you sure the function push handles undefined variables?
Loading history...
20690
          }
20691
          else if(returnedValue !== undefined) {
20692
            returnedValue = [returnedValue, response];
20693
          }
20694
          else if(response !== undefined) {
20695
            returnedValue = response;
20696
          }
20697
          return found;
20698
        }
20699
      };
20700
20701
      if(methodInvoked) {
20702
        if(instance === undefined) {
20703
          module.initialize();
20704
        }
20705
        module.invoke(query);
20706
      }
20707
      else {
20708
        if(instance !== undefined) {
20709
          instance.invoke('destroy');
20710
        }
20711
        module.initialize();
20712
      }
20713
    })
20714
  ;
20715
20716
  return (returnedValue !== undefined)
20717
    ? returnedValue
20718
    : this
20719
  ;
20720
};
20721
20722
$.api.settings = {
20723
20724
  name              : 'API',
20725
  namespace         : 'api',
20726
20727
  debug             : false,
20728
  verbose           : false,
20729
  performance       : true,
20730
20731
  // object containing all templates endpoints
20732
  api               : {},
20733
20734
  // whether to cache responses
20735
  cache             : true,
20736
20737
  // whether new requests should abort previous requests
20738
  interruptRequests : true,
20739
20740
  // event binding
20741
  on                : 'auto',
20742
20743
  // context for applying state classes
20744
  stateContext      : false,
20745
20746
  // duration for loading state
20747
  loadingDuration   : 0,
20748
20749
  // whether to hide errors after a period of time
20750
  hideError         : 'auto',
20751
20752
  // duration for error state
20753
  errorDuration     : 2000,
20754
20755
  // whether parameters should be encoded with encodeURIComponent
20756
  encodeParameters  : true,
20757
20758
  // API action to use
20759
  action            : false,
20760
20761
  // templated URL to use
20762
  url               : false,
20763
20764
  // base URL to apply to all endpoints
20765
  base              : '',
20766
20767
  // data that will
20768
  urlData           : {},
20769
20770
  // whether to add default data to url data
20771
  defaultData          : true,
20772
20773
  // whether to serialize closest form
20774
  serializeForm        : false,
20775
20776
  // how long to wait before request should occur
20777
  throttle             : 0,
20778
20779
  // whether to throttle first request or only repeated
20780
  throttleFirstRequest : true,
20781
20782
  // standard ajax settings
20783
  method            : 'get',
20784
  data              : {},
20785
  dataType          : 'json',
20786
20787
  // mock response
20788
  mockResponse      : false,
20789
  mockResponseAsync : false,
20790
20791
  // aliases for mock
20792
  response          : false,
20793
  responseAsync     : false,
20794
20795
  // callbacks before request
20796
  beforeSend  : function(settings) { return settings; },
20797
  beforeXHR   : function(xhr) {},
0 ignored issues
show
Unused Code introduced by
The parameter xhr is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
20798
  onRequest   : function(promise, xhr) {},
0 ignored issues
show
Unused Code introduced by
The parameter promise is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter xhr is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
20799
20800
  // after request
20801
  onResponse  : false, // function(response) { },
20802
20803
  // response was successful, if JSON passed validation
20804
  onSuccess   : function(response, $module) {},
0 ignored issues
show
Unused Code introduced by
The parameter response is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter $module is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
20805
20806
  // request finished without aborting
20807
  onComplete  : function(response, $module) {},
0 ignored issues
show
Unused Code introduced by
The parameter $module is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter response is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
20808
20809
  // failed JSON success test
20810
  onFailure   : function(response, $module) {},
0 ignored issues
show
Unused Code introduced by
The parameter response is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter $module is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
20811
20812
  // server error
20813
  onError     : function(errorMessage, $module) {},
0 ignored issues
show
Unused Code introduced by
The parameter errorMessage is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter $module is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
20814
20815
  // request aborted
20816
  onAbort     : function(errorMessage, $module) {},
0 ignored issues
show
Unused Code introduced by
The parameter $module is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
Unused Code introduced by
The parameter errorMessage is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
20817
20818
  successTest : false,
20819
20820
  // errors
20821
  error : {
20822
    beforeSend        : 'The before send function has aborted the request',
20823
    error             : 'There was an error with your request',
20824
    exitConditions    : 'API Request Aborted. Exit conditions met',
20825
    JSONParse         : 'JSON could not be parsed during error handling',
20826
    legacyParameters  : 'You are using legacy API success callback names',
20827
    method            : 'The method you called is not defined',
20828
    missingAction     : 'API action used but no url was defined',
20829
    missingSerialize  : 'jquery-serialize-object is required to add form data to an existing data object',
20830
    missingURL        : 'No URL specified for api event',
20831
    noReturnedValue   : 'The beforeSend callback must return a settings object, beforeSend ignored.',
20832
    noStorage         : 'Caching responses locally requires session storage',
20833
    parseError        : 'There was an error parsing your request',
20834
    requiredParameter : 'Missing a required URL parameter: ',
20835
    statusMessage     : 'Server gave an error: ',
20836
    timeout           : 'Your request timed out'
20837
  },
20838
20839
  regExp  : {
20840
    required : /\{\$*[A-z0-9]+\}/g,
20841
    optional : /\{\/\$*[A-z0-9]+\}/g,
20842
  },
20843
20844
  className: {
20845
    loading : 'loading',
20846
    error   : 'error'
20847
  },
20848
20849
  selector: {
20850
    disabled : '.disabled',
20851
    form      : 'form'
20852
  },
20853
20854
  metadata: {
20855
    action  : 'action',
20856
    url     : 'url'
20857
  }
20858
};
20859
20860
20861
20862
})( jQuery, window, document );
20863
20864
/*!
20865
 * # Semantic UI 2.2.11 - State
20866
 * http://github.com/semantic-org/semantic-ui/
20867
 *
20868
 *
20869
 * Released under the MIT license
20870
 * http://opensource.org/licenses/MIT
20871
 *
20872
 */
20873
20874 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
20875
20876
"use strict";
20877
20878
window = (typeof window != 'undefined' && window.Math == Math)
0 ignored issues
show
Unused Code introduced by
The assignment to variable window seems to be never used. Consider removing it.
Loading history...
20879
  ? window
20880
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
20881
    ? self
20882
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
20883
;
20884
20885
$.fn.state = function(parameters) {
20886
  var
20887
    $allModules     = $(this),
20888
20889
    moduleSelector  = $allModules.selector || '',
20890
20891
    hasTouch        = ('ontouchstart' in document.documentElement),
0 ignored issues
show
Unused Code introduced by
The variable hasTouch seems to be never used. Consider removing it.
Loading history...
20892
    time            = new Date().getTime(),
20893
    performance     = [],
20894
20895
    query           = arguments[0],
20896
    methodInvoked   = (typeof query == 'string'),
20897
    queryArguments  = [].slice.call(arguments, 1),
20898
20899
    returnedValue
20900
  ;
20901
  $allModules
20902
    .each(function() {
20903
      var
20904
        settings          = ( $.isPlainObject(parameters) )
20905
          ? $.extend(true, {}, $.fn.state.settings, parameters)
20906
          : $.extend({}, $.fn.state.settings),
20907
20908
        error           = settings.error,
20909
        metadata        = settings.metadata,
20910
        className       = settings.className,
20911
        namespace       = settings.namespace,
20912
        states          = settings.states,
20913
        text            = settings.text,
20914
20915
        eventNamespace  = '.' + namespace,
20916
        moduleNamespace = namespace + '-module',
20917
20918
        $module         = $(this),
20919
20920
        element         = this,
20921
        instance        = $module.data(moduleNamespace),
20922
20923
        module
20924
      ;
20925
      module = {
20926
20927
        initialize: function() {
20928
          module.verbose('Initializing module');
20929
20930
          // allow module to guess desired state based on element
20931
          if(settings.automatic) {
20932
            module.add.defaults();
20933
          }
20934
20935
          // bind events with delegated events
20936
          if(settings.context && moduleSelector !== '') {
20937
            $(settings.context)
20938
              .on(moduleSelector, 'mouseenter' + eventNamespace, module.change.text)
20939
              .on(moduleSelector, 'mouseleave' + eventNamespace, module.reset.text)
20940
              .on(moduleSelector, 'click'      + eventNamespace, module.toggle.state)
20941
            ;
20942
          }
20943
          else {
20944
            $module
20945
              .on('mouseenter' + eventNamespace, module.change.text)
20946
              .on('mouseleave' + eventNamespace, module.reset.text)
20947
              .on('click'      + eventNamespace, module.toggle.state)
20948
            ;
20949
          }
20950
          module.instantiate();
20951
        },
20952
20953
        instantiate: function() {
20954
          module.verbose('Storing instance of module', module);
20955
          instance = module;
20956
          $module
20957
            .data(moduleNamespace, module)
20958
          ;
20959
        },
20960
20961
        destroy: function() {
20962
          module.verbose('Destroying previous module', instance);
20963
          $module
20964
            .off(eventNamespace)
20965
            .removeData(moduleNamespace)
20966
          ;
20967
        },
20968
20969
        refresh: function() {
20970
          module.verbose('Refreshing selector cache');
20971
          $module = $(element);
20972
        },
20973
20974
        add: {
20975
          defaults: function() {
20976
            var
20977
              userStates = parameters && $.isPlainObject(parameters.states)
20978
                ? parameters.states
20979
                : {}
20980
            ;
20981
            $.each(settings.defaults, function(type, typeStates) {
20982
              if( module.is[type] !== undefined && module.is[type]() ) {
20983
                module.verbose('Adding default states', type, element);
20984
                $.extend(settings.states, typeStates, userStates);
20985
              }
20986
            });
20987
          }
20988
        },
20989
20990
        is: {
20991
20992
          active: function() {
20993
            return $module.hasClass(className.active);
20994
          },
20995
          loading: function() {
20996
            return $module.hasClass(className.loading);
20997
          },
20998
          inactive: function() {
20999
            return !( $module.hasClass(className.active) );
21000
          },
21001
          state: function(state) {
21002
            if(className[state] === undefined) {
21003
              return false;
21004
            }
21005
            return $module.hasClass( className[state] );
21006
          },
21007
21008
          enabled: function() {
21009
            return !( $module.is(settings.filter.active) );
21010
          },
21011
          disabled: function() {
21012
            return ( $module.is(settings.filter.active) );
21013
          },
21014
          textEnabled: function() {
21015
            return !( $module.is(settings.filter.text) );
21016
          },
21017
21018
          // definitions for automatic type detection
21019
          button: function() {
21020
            return $module.is('.button:not(a, .submit)');
21021
          },
21022
          input: function() {
21023
            return $module.is('input');
21024
          },
21025
          progress: function() {
21026
            return $module.is('.ui.progress');
21027
          }
21028
        },
21029
21030
        allow: function(state) {
21031
          module.debug('Now allowing state', state);
21032
          states[state] = true;
21033
        },
21034
        disallow: function(state) {
21035
          module.debug('No longer allowing', state);
21036
          states[state] = false;
21037
        },
21038
21039
        allows: function(state) {
21040
          return states[state] || false;
21041
        },
21042
21043
        enable: function() {
21044
          $module.removeClass(className.disabled);
21045
        },
21046
21047
        disable: function() {
21048
          $module.addClass(className.disabled);
21049
        },
21050
21051
        setState: function(state) {
21052
          if(module.allows(state)) {
21053
            $module.addClass( className[state] );
21054
          }
21055
        },
21056
21057
        removeState: function(state) {
21058
          if(module.allows(state)) {
21059
            $module.removeClass( className[state] );
21060
          }
21061
        },
21062
21063
        toggle: {
21064
          state: function() {
21065
            var
21066
              apiRequest,
21067
              requestCancelled
21068
            ;
21069
            if( module.allows('active') && module.is.enabled() ) {
21070
              module.refresh();
21071
              if($.fn.api !== undefined) {
21072
                apiRequest       = $module.api('get request');
21073
                requestCancelled = $module.api('was cancelled');
21074
                if( requestCancelled ) {
21075
                  module.debug('API Request cancelled by beforesend');
21076
                  settings.activateTest   = function(){ return false; };
21077
                  settings.deactivateTest = function(){ return false; };
21078
                }
21079
                else if(apiRequest) {
21080
                  module.listenTo(apiRequest);
21081
                  return;
21082
                }
21083
              }
21084
              module.change.state();
21085
            }
21086
          }
21087
        },
21088
21089
        listenTo: function(apiRequest) {
21090
          module.debug('API request detected, waiting for state signal', apiRequest);
21091
          if(apiRequest) {
21092
            if(text.loading) {
21093
              module.update.text(text.loading);
21094
            }
21095
            $.when(apiRequest)
21096
              .then(function() {
21097
                if(apiRequest.state() == 'resolved') {
21098
                  module.debug('API request succeeded');
21099
                  settings.activateTest   = function(){ return true; };
21100
                  settings.deactivateTest = function(){ return true; };
21101
                }
21102
                else {
21103
                  module.debug('API request failed');
21104
                  settings.activateTest   = function(){ return false; };
21105
                  settings.deactivateTest = function(){ return false; };
21106
                }
21107
                module.change.state();
21108
              })
21109
            ;
21110
          }
21111
        },
21112
21113
        // checks whether active/inactive state can be given
21114
        change: {
21115
21116
          state: function() {
21117
            module.debug('Determining state change direction');
21118
            // inactive to active change
21119
            if( module.is.inactive() ) {
21120
              module.activate();
21121
            }
21122
            else {
21123
              module.deactivate();
21124
            }
21125
            if(settings.sync) {
21126
              module.sync();
21127
            }
21128
            settings.onChange.call(element);
21129
          },
21130
21131
          text: function() {
21132
            if( module.is.textEnabled() ) {
21133
              if(module.is.disabled() ) {
21134
                module.verbose('Changing text to disabled text', text.hover);
21135
                module.update.text(text.disabled);
21136
              }
21137
              else if( module.is.active() ) {
21138
                if(text.hover) {
21139
                  module.verbose('Changing text to hover text', text.hover);
21140
                  module.update.text(text.hover);
21141
                }
21142
                else if(text.deactivate) {
21143
                  module.verbose('Changing text to deactivating text', text.deactivate);
21144
                  module.update.text(text.deactivate);
21145
                }
21146
              }
21147
              else {
21148
                if(text.hover) {
21149
                  module.verbose('Changing text to hover text', text.hover);
21150
                  module.update.text(text.hover);
21151
                }
21152
                else if(text.activate){
21153
                  module.verbose('Changing text to activating text', text.activate);
21154
                  module.update.text(text.activate);
21155
                }
21156
              }
21157
            }
21158
          }
21159
21160
        },
21161
21162
        activate: function() {
21163
          if( settings.activateTest.call(element) ) {
21164
            module.debug('Setting state to active');
21165
            $module
21166
              .addClass(className.active)
21167
            ;
21168
            module.update.text(text.active);
21169
            settings.onActivate.call(element);
21170
          }
21171
        },
21172
21173
        deactivate: function() {
21174
          if( settings.deactivateTest.call(element) ) {
21175
            module.debug('Setting state to inactive');
21176
            $module
21177
              .removeClass(className.active)
21178
            ;
21179
            module.update.text(text.inactive);
21180
            settings.onDeactivate.call(element);
21181
          }
21182
        },
21183
21184
        sync: function() {
21185
          module.verbose('Syncing other buttons to current state');
21186
          if( module.is.active() ) {
21187
            $allModules
21188
              .not($module)
21189
                .state('activate');
21190
          }
21191
          else {
21192
            $allModules
21193
              .not($module)
21194
                .state('deactivate')
21195
            ;
21196
          }
21197
        },
21198
21199
        get: {
21200
          text: function() {
21201
            return (settings.selector.text)
21202
              ? $module.find(settings.selector.text).text()
21203
              : $module.html()
21204
            ;
21205
          },
21206
          textFor: function(state) {
21207
            return text[state] || false;
21208
          }
21209
        },
21210
21211
        flash: {
21212
          text: function(text, duration, callback) {
21213
            var
21214
              previousText = module.get.text()
21215
            ;
21216
            module.debug('Flashing text message', text, duration);
21217
            text     = text     || settings.text.flash;
21218
            duration = duration || settings.flashDuration;
21219
            callback = callback || function() {};
21220
            module.update.text(text);
21221
            setTimeout(function(){
21222
              module.update.text(previousText);
21223
              callback.call(element);
21224
            }, duration);
21225
          }
21226
        },
21227
21228
        reset: {
21229
          // on mouseout sets text to previous value
21230
          text: function() {
21231
            var
21232
              activeText   = text.active   || $module.data(metadata.storedText),
21233
              inactiveText = text.inactive || $module.data(metadata.storedText)
21234
            ;
21235
            if( module.is.textEnabled() ) {
21236
              if( module.is.active() && activeText) {
21237
                module.verbose('Resetting active text', activeText);
21238
                module.update.text(activeText);
21239
              }
21240
              else if(inactiveText) {
21241
                module.verbose('Resetting inactive text', activeText);
21242
                module.update.text(inactiveText);
21243
              }
21244
            }
21245
          }
21246
        },
21247
21248
        update: {
21249
          text: function(text) {
21250
            var
21251
              currentText = module.get.text()
21252
            ;
21253
            if(text && text !== currentText) {
21254
              module.debug('Updating text', text);
21255
              if(settings.selector.text) {
21256
                $module
21257
                  .data(metadata.storedText, text)
21258
                  .find(settings.selector.text)
21259
                    .text(text)
21260
                ;
21261
              }
21262
              else {
21263
                $module
21264
                  .data(metadata.storedText, text)
21265
                  .html(text)
21266
                ;
21267
              }
21268
            }
21269
            else {
21270
              module.debug('Text is already set, ignoring update', text);
21271
            }
21272
          }
21273
        },
21274
21275
        setting: function(name, value) {
21276
          module.debug('Changing setting', name, value);
21277
          if( $.isPlainObject(name) ) {
21278
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
21279
          }
21280
          else if(value !== undefined) {
21281
            if($.isPlainObject(settings[name])) {
21282
              $.extend(true, settings[name], value);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
21283
            }
21284
            else {
21285
              settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
21286
            }
21287
          }
21288
          else {
21289
            return settings[name];
21290
          }
21291
        },
21292
        internal: function(name, value) {
21293
          if( $.isPlainObject(name) ) {
21294
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
21295
          }
21296
          else if(value !== undefined) {
21297
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
21298
          }
21299
          else {
21300
            return module[name];
21301
          }
21302
        },
21303
        debug: function() {
21304
          if(!settings.silent && settings.debug) {
21305
            if(settings.performance) {
21306
              module.performance.log(arguments);
21307
            }
21308
            else {
21309
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
21310
              module.debug.apply(console, arguments);
21311
            }
21312
          }
21313
        },
21314
        verbose: function() {
21315
          if(!settings.silent && settings.verbose && settings.debug) {
21316
            if(settings.performance) {
21317
              module.performance.log(arguments);
21318
            }
21319
            else {
21320
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
21321
              module.verbose.apply(console, arguments);
21322
            }
21323
          }
21324
        },
21325
        error: function() {
21326
          if(!settings.silent) {
21327
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
21328
            module.error.apply(console, arguments);
21329
          }
21330
        },
21331
        performance: {
21332
          log: function(message) {
21333
            var
21334
              currentTime,
21335
              executionTime,
21336
              previousTime
21337
            ;
21338
            if(settings.performance) {
21339
              currentTime   = new Date().getTime();
21340
              previousTime  = time || currentTime;
21341
              executionTime = currentTime - previousTime;
21342
              time          = currentTime;
21343
              performance.push({
21344
                'Name'           : message[0],
21345
                'Arguments'      : [].slice.call(message, 1) || '',
21346
                'Element'        : element,
21347
                'Execution Time' : executionTime
21348
              });
21349
            }
21350
            clearTimeout(module.performance.timer);
21351
            module.performance.timer = setTimeout(module.performance.display, 500);
21352
          },
21353
          display: function() {
21354
            var
21355
              title = settings.name + ':',
21356
              totalTime = 0
21357
            ;
21358
            time = false;
21359
            clearTimeout(module.performance.timer);
21360
            $.each(performance, function(index, data) {
21361
              totalTime += data['Execution Time'];
21362
            });
21363
            title += ' ' + totalTime + 'ms';
21364
            if(moduleSelector) {
21365
              title += ' \'' + moduleSelector + '\'';
21366
            }
21367
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
21368
              console.groupCollapsed(title);
21369
              if(console.table) {
21370
                console.table(performance);
21371
              }
21372
              else {
21373
                $.each(performance, function(index, data) {
21374
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
21375
                });
21376
              }
21377
              console.groupEnd();
21378
            }
21379
            performance = [];
21380
          }
21381
        },
21382
        invoke: function(query, passedArguments, context) {
21383
          var
21384
            object = instance,
21385
            maxDepth,
21386
            found,
21387
            response
21388
          ;
21389
          passedArguments = passedArguments || queryArguments;
21390
          context         = element         || context;
21391
          if(typeof query == 'string' && object !== undefined) {
21392
            query    = query.split(/[\. ]/);
21393
            maxDepth = query.length - 1;
21394
            $.each(query, function(depth, value) {
21395
              var camelCaseValue = (depth != maxDepth)
21396
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
21397
                : query
21398
              ;
21399
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
21400
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
21401
              }
21402
              else if( object[camelCaseValue] !== undefined ) {
21403
                found = object[camelCaseValue];
21404
                return false;
21405
              }
21406
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
21407
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
21408
              }
21409
              else if( object[value] !== undefined ) {
21410
                found = object[value];
21411
                return false;
21412
              }
21413
              else {
21414
                module.error(error.method, query);
21415
                return false;
21416
              }
21417
            });
21418
          }
21419
          if ( $.isFunction( found ) ) {
21420
            response = found.apply(context, passedArguments);
21421
          }
21422
          else if(found !== undefined) {
21423
            response = found;
21424
          }
21425
          if($.isArray(returnedValue)) {
21426
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 21422 is false. Are you sure the function push handles undefined variables?
Loading history...
21427
          }
21428
          else if(returnedValue !== undefined) {
21429
            returnedValue = [returnedValue, response];
21430
          }
21431
          else if(response !== undefined) {
21432
            returnedValue = response;
21433
          }
21434
          return found;
21435
        }
21436
      };
21437
21438
      if(methodInvoked) {
21439
        if(instance === undefined) {
21440
          module.initialize();
21441
        }
21442
        module.invoke(query);
21443
      }
21444
      else {
21445
        if(instance !== undefined) {
21446
          instance.invoke('destroy');
21447
        }
21448
        module.initialize();
21449
      }
21450
    })
21451
  ;
21452
21453
  return (returnedValue !== undefined)
21454
    ? returnedValue
21455
    : this
21456
  ;
21457
};
21458
21459
$.fn.state.settings = {
21460
21461
  // module info
21462
  name           : 'State',
21463
21464
  // debug output
21465
  debug          : false,
21466
21467
  // verbose debug output
21468
  verbose        : false,
21469
21470
  // namespace for events
21471
  namespace      : 'state',
21472
21473
  // debug data includes performance
21474
  performance    : true,
21475
21476
  // callback occurs on state change
21477
  onActivate     : function() {},
21478
  onDeactivate   : function() {},
21479
  onChange       : function() {},
21480
21481
  // state test functions
21482
  activateTest   : function() { return true; },
21483
  deactivateTest : function() { return true; },
21484
21485
  // whether to automatically map default states
21486
  automatic      : true,
21487
21488
  // activate / deactivate changes all elements instantiated at same time
21489
  sync           : false,
21490
21491
  // default flash text duration, used for temporarily changing text of an element
21492
  flashDuration  : 1000,
21493
21494
  // selector filter
21495
  filter     : {
21496
    text   : '.loading, .disabled',
21497
    active : '.disabled'
21498
  },
21499
21500
  context    : false,
21501
21502
  // error
21503
  error: {
21504
    beforeSend : 'The before send function has cancelled state change',
21505
    method     : 'The method you called is not defined.'
21506
  },
21507
21508
  // metadata
21509
  metadata: {
21510
    promise    : 'promise',
21511
    storedText : 'stored-text'
21512
  },
21513
21514
  // change class on state
21515
  className: {
21516
    active   : 'active',
21517
    disabled : 'disabled',
21518
    error    : 'error',
21519
    loading  : 'loading',
21520
    success  : 'success',
21521
    warning  : 'warning'
21522
  },
21523
21524
  selector: {
21525
    // selector for text node
21526
    text: false
21527
  },
21528
21529
  defaults : {
21530
    input: {
21531
      disabled : true,
21532
      loading  : true,
21533
      active   : true
21534
    },
21535
    button: {
21536
      disabled : true,
21537
      loading  : true,
21538
      active   : true,
21539
    },
21540
    progress: {
21541
      active   : true,
21542
      success  : true,
21543
      warning  : true,
21544
      error    : true
21545
    }
21546
  },
21547
21548
  states     : {
21549
    active   : true,
21550
    disabled : true,
21551
    error    : true,
21552
    loading  : true,
21553
    success  : true,
21554
    warning  : true
21555
  },
21556
21557
  text     : {
21558
    disabled   : false,
21559
    flash      : false,
21560
    hover      : false,
21561
    active     : false,
21562
    inactive   : false,
21563
    activate   : false,
21564
    deactivate : false
21565
  }
21566
21567
};
21568
21569
21570
21571
})( jQuery, window, document );
21572
21573
/*!
21574
 * # Semantic UI 2.2.11 - Visibility
21575
 * http://github.com/semantic-org/semantic-ui/
21576
 *
21577
 *
21578
 * Released under the MIT license
21579
 * http://opensource.org/licenses/MIT
21580
 *
21581
 */
21582
21583 View Code Duplication
;(function ($, window, document, undefined) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
21584
21585
"use strict";
21586
21587
window = (typeof window != 'undefined' && window.Math == Math)
21588
  ? window
21589
  : (typeof self != 'undefined' && self.Math == Math)
0 ignored issues
show
Bug introduced by
The variable self seems to be never declared. If this is a global, consider adding a /** global: self */ 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...
21590
    ? self
21591
    : Function('return this')()
0 ignored issues
show
Performance Best Practice introduced by
Using new Function() to create a function is slow and difficult to debug. Such functions do not create a closure. Consider using another way to define your function.
Loading history...
21592
;
21593
21594
$.fn.visibility = function(parameters) {
21595
  var
21596
    $allModules    = $(this),
21597
    moduleSelector = $allModules.selector || '',
21598
21599
    time           = new Date().getTime(),
21600
    performance    = [],
21601
21602
    query          = arguments[0],
21603
    methodInvoked  = (typeof query == 'string'),
21604
    queryArguments = [].slice.call(arguments, 1),
21605
    returnedValue,
21606
21607
    moduleCount    = $allModules.length,
21608
    loadedCount    = 0
21609
  ;
21610
21611
  $allModules
21612
    .each(function() {
21613
      var
21614
        settings        = ( $.isPlainObject(parameters) )
21615
          ? $.extend(true, {}, $.fn.visibility.settings, parameters)
21616
          : $.extend({}, $.fn.visibility.settings),
21617
21618
        className       = settings.className,
21619
        namespace       = settings.namespace,
21620
        error           = settings.error,
21621
        metadata        = settings.metadata,
21622
21623
        eventNamespace  = '.' + namespace,
21624
        moduleNamespace = 'module-' + namespace,
21625
21626
        $window         = $(window),
21627
21628
        $module         = $(this),
21629
        $context        = $(settings.context),
21630
21631
        $placeholder,
21632
21633
        selector        = $module.selector || '',
0 ignored issues
show
Unused Code introduced by
The assignment to variable selector seems to be never used. Consider removing it.
Loading history...
21634
        instance        = $module.data(moduleNamespace),
21635
21636
        requestAnimationFrame = window.requestAnimationFrame
21637
          || window.mozRequestAnimationFrame
21638
          || window.webkitRequestAnimationFrame
21639
          || window.msRequestAnimationFrame
21640
          || function(callback) { setTimeout(callback, 0); },
21641
21642
        element         = this,
21643
        disabled        = false,
21644
21645
        contextObserver,
21646
        observer,
21647
        module
21648
      ;
21649
21650
      module = {
21651
21652
        initialize: function() {
21653
          module.debug('Initializing', settings);
21654
21655
          module.setup.cache();
21656
21657
          if( module.should.trackChanges() ) {
21658
21659
            if(settings.type == 'image') {
21660
              module.setup.image();
21661
            }
21662
            if(settings.type == 'fixed') {
21663
              module.setup.fixed();
21664
            }
21665
21666
            if(settings.observeChanges) {
21667
              module.observeChanges();
21668
            }
21669
            module.bind.events();
21670
          }
21671
21672
          module.save.position();
21673
          if( !module.is.visible() ) {
21674
            module.error(error.visible, $module);
21675
          }
21676
21677
          if(settings.initialCheck) {
21678
            module.checkVisibility();
21679
          }
21680
          module.instantiate();
21681
        },
21682
21683
        instantiate: function() {
21684
          module.debug('Storing instance', module);
21685
          $module
21686
            .data(moduleNamespace, module)
21687
          ;
21688
          instance = module;
21689
        },
21690
21691
        destroy: function() {
21692
          module.verbose('Destroying previous module');
21693
          if(observer) {
21694
            observer.disconnect();
21695
          }
21696
          if(contextObserver) {
21697
            contextObserver.disconnect();
21698
          }
21699
          $window
21700
            .off('load'   + eventNamespace, module.event.load)
21701
            .off('resize' + eventNamespace, module.event.resize)
21702
          ;
21703
          $context
21704
            .off('scroll'       + eventNamespace, module.event.scroll)
21705
            .off('scrollchange' + eventNamespace, module.event.scrollchange)
21706
          ;
21707
          if(settings.type == 'fixed') {
21708
            module.resetFixed();
21709
            module.remove.placeholder();
21710
          }
21711
          $module
21712
            .off(eventNamespace)
21713
            .removeData(moduleNamespace)
21714
          ;
21715
        },
21716
21717
        observeChanges: function() {
21718
          if('MutationObserver' in window) {
21719
            contextObserver = new MutationObserver(module.event.contextChanged);
0 ignored issues
show
Bug introduced by
The variable MutationObserver seems to be never declared. If this is a global, consider adding a /** global: MutationObserver */ 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...
21720
            observer        = new MutationObserver(module.event.changed);
21721
            contextObserver.observe(document, {
21722
              childList : true,
21723
              subtree   : true
21724
            });
21725
            observer.observe(element, {
21726
              childList : true,
21727
              subtree   : true
21728
            });
21729
            module.debug('Setting up mutation observer', observer);
21730
          }
21731
        },
21732
21733
        bind: {
21734
          events: function() {
21735
            module.verbose('Binding visibility events to scroll and resize');
21736
            if(settings.refreshOnLoad) {
21737
              $window
21738
                .on('load'   + eventNamespace, module.event.load)
21739
              ;
21740
            }
21741
            $window
21742
              .on('resize' + eventNamespace, module.event.resize)
21743
            ;
21744
            // pub/sub pattern
21745
            $context
21746
              .off('scroll'      + eventNamespace)
21747
              .on('scroll'       + eventNamespace, module.event.scroll)
21748
              .on('scrollchange' + eventNamespace, module.event.scrollchange)
21749
            ;
21750
          }
21751
        },
21752
21753
        event: {
21754
          changed: function(mutations) {
0 ignored issues
show
Unused Code introduced by
The parameter mutations is not used and could be removed.

This check looks for parameters in functions that are not used in the function body and are not followed by other parameters which are used inside the function.

Loading history...
21755
            module.verbose('DOM tree modified, updating visibility calculations');
21756
            module.timer = setTimeout(function() {
21757
              module.verbose('DOM tree modified, updating sticky menu');
21758
              module.refresh();
21759
            }, 100);
21760
          },
21761
          contextChanged: function(mutations) {
21762
            [].forEach.call(mutations, function(mutation) {
21763
              if(mutation.removedNodes) {
21764
                [].forEach.call(mutation.removedNodes, function(node) {
21765
                  if(node == element || $(node).find(element).length > 0) {
21766
                    module.debug('Element removed from DOM, tearing down events');
21767
                    module.destroy();
21768
                  }
21769
                });
21770
              }
21771
            });
21772
          },
21773
          resize: function() {
21774
            module.debug('Window resized');
21775
            if(settings.refreshOnResize) {
21776
              requestAnimationFrame(module.refresh);
21777
            }
21778
          },
21779
          load: function() {
21780
            module.debug('Page finished loading');
21781
            requestAnimationFrame(module.refresh);
21782
          },
21783
          // publishes scrollchange event on one scroll
21784
          scroll: function() {
21785
            if(settings.throttle) {
21786
              clearTimeout(module.timer);
21787
              module.timer = setTimeout(function() {
21788
                $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]);
21789
              }, settings.throttle);
21790
            }
21791
            else {
21792
              requestAnimationFrame(function() {
21793
                $context.triggerHandler('scrollchange' + eventNamespace, [ $context.scrollTop() ]);
21794
              });
21795
            }
21796
          },
21797
          // subscribes to scrollchange
21798
          scrollchange: function(event, scrollPosition) {
21799
            module.checkVisibility(scrollPosition);
21800
          },
21801
        },
21802
21803
        precache: function(images, callback) {
21804
          if (!(images instanceof Array)) {
21805
            images = [images];
21806
          }
21807
          var
21808
            imagesLength  = images.length,
21809
            loadedCounter = 0,
21810
            cache         = [],
21811
            cacheImage    = document.createElement('img'),
0 ignored issues
show
Unused Code introduced by
The assignment to variable cacheImage seems to be never used. Consider removing it.
Loading history...
21812
            handleLoad    = function() {
21813
              loadedCounter++;
21814
              if (loadedCounter >= images.length) {
21815
                if ($.isFunction(callback)) {
21816
                  callback();
21817
                }
21818
              }
21819
            }
21820
          ;
21821
          while (imagesLength--) {
21822
            cacheImage         = document.createElement('img');
21823
            cacheImage.onload  = handleLoad;
21824
            cacheImage.onerror = handleLoad;
21825
            cacheImage.src     = images[imagesLength];
21826
            cache.push(cacheImage);
21827
          }
21828
        },
21829
21830
        enableCallbacks: function() {
21831
          module.debug('Allowing callbacks to occur');
21832
          disabled = false;
21833
        },
21834
21835
        disableCallbacks: function() {
21836
          module.debug('Disabling all callbacks temporarily');
21837
          disabled = true;
21838
        },
21839
21840
        should: {
21841
          trackChanges: function() {
21842
            if(methodInvoked) {
21843
              module.debug('One time query, no need to bind events');
21844
              return false;
21845
            }
21846
            module.debug('Callbacks being attached');
21847
            return true;
21848
          }
21849
        },
21850
21851
        setup: {
21852
          cache: function() {
21853
            module.cache = {
21854
              occurred : {},
21855
              screen   : {},
21856
              element  : {},
21857
            };
21858
          },
21859
          image: function() {
21860
            var
21861
              src = $module.data(metadata.src)
21862
            ;
21863
            if(src) {
21864
              module.verbose('Lazy loading image', src);
21865
              settings.once           = true;
21866
              settings.observeChanges = false;
21867
21868
              // show when top visible
21869
              settings.onOnScreen = function() {
21870
                module.debug('Image on screen', element);
21871
                module.precache(src, function() {
21872
                  module.set.image(src, function() {
21873
                    loadedCount++;
21874
                    if(loadedCount == moduleCount) {
21875
                      settings.onAllLoaded.call(this);
21876
                    }
21877
                    settings.onLoad.call(this);
21878
                  });
21879
                });
21880
              };
21881
            }
21882
          },
21883
          fixed: function() {
21884
            module.debug('Setting up fixed');
21885
            settings.once           = false;
21886
            settings.observeChanges = false;
21887
            settings.initialCheck   = true;
21888
            settings.refreshOnLoad  = true;
21889
            if(!parameters.transition) {
21890
              settings.transition = false;
21891
            }
21892
            module.create.placeholder();
21893
            module.debug('Added placeholder', $placeholder);
21894
            settings.onTopPassed = function() {
21895
              module.debug('Element passed, adding fixed position', $module);
21896
              module.show.placeholder();
21897
              module.set.fixed();
21898
              if(settings.transition) {
21899
                if($.fn.transition !== undefined) {
21900
                  $module.transition(settings.transition, settings.duration);
21901
                }
21902
              }
21903
            };
21904
            settings.onTopPassedReverse = function() {
21905
              module.debug('Element returned to position, removing fixed', $module);
21906
              module.hide.placeholder();
21907
              module.remove.fixed();
21908
            };
21909
          }
21910
        },
21911
21912
        create: {
21913
          placeholder: function() {
21914
            module.verbose('Creating fixed position placeholder');
21915
            $placeholder = $module
21916
              .clone(false)
21917
              .css('display', 'none')
21918
              .addClass(className.placeholder)
21919
              .insertAfter($module)
21920
            ;
21921
          }
21922
        },
21923
21924
        show: {
21925
          placeholder: function() {
21926
            module.verbose('Showing placeholder');
21927
            $placeholder
21928
              .css('display', 'block')
21929
              .css('visibility', 'hidden')
21930
            ;
21931
          }
21932
        },
21933
        hide: {
21934
          placeholder: function() {
21935
            module.verbose('Hiding placeholder');
21936
            $placeholder
21937
              .css('display', 'none')
21938
              .css('visibility', '')
21939
            ;
21940
          }
21941
        },
21942
21943
        set: {
21944
          fixed: function() {
21945
            module.verbose('Setting element to fixed position');
21946
            $module
21947
              .addClass(className.fixed)
21948
              .css({
21949
                position : 'fixed',
21950
                top      : settings.offset + 'px',
21951
                left     : 'auto',
21952
                zIndex   : settings.zIndex
21953
              })
21954
            ;
21955
            settings.onFixed.call(element);
21956
          },
21957
          image: function(src, callback) {
21958
            $module
21959
              .attr('src', src)
21960
            ;
21961
            if(settings.transition) {
21962
              if( $.fn.transition !== undefined) {
21963
                if($module.hasClass(className.visible)) {
21964
                  module.debug('Transition already occurred on this image, skipping animation');
21965
                  return;
21966
                }
21967
                $module.transition(settings.transition, settings.duration, callback);
21968
              }
21969
              else {
21970
                $module.fadeIn(settings.duration, callback);
21971
              }
21972
            }
21973
            else {
21974
              $module.show();
21975
            }
21976
          }
21977
        },
21978
21979
        is: {
21980
          onScreen: function() {
21981
            var
21982
              calculations   = module.get.elementCalculations()
21983
            ;
21984
            return calculations.onScreen;
21985
          },
21986
          offScreen: function() {
21987
            var
21988
              calculations   = module.get.elementCalculations()
21989
            ;
21990
            return calculations.offScreen;
21991
          },
21992
          visible: function() {
21993
            if(module.cache && module.cache.element) {
21994
              return !(module.cache.element.width === 0 && module.cache.element.offset.top === 0);
21995
            }
21996
            return false;
21997
          },
21998
          verticallyScrollableContext: function() {
21999
            var
22000
              overflowY = ($context.get(0) !== window)
22001
                ? $context.css('overflow-y')
22002
                : false
22003
            ;
22004
            return (overflowY == 'auto' || overflowY == 'scroll');
22005
          },
22006
          horizontallyScrollableContext: function() {
22007
            var
22008
              overflowX = ($context.get(0) !== window)
22009
                ? $context.css('overflow-x')
22010
                : false
22011
            ;
22012
            return (overflowX == 'auto' || overflowX == 'scroll');
22013
          }
22014
        },
22015
22016
        refresh: function() {
22017
          module.debug('Refreshing constants (width/height)');
22018
          if(settings.type == 'fixed') {
22019
            module.resetFixed();
22020
          }
22021
          module.reset();
22022
          module.save.position();
22023
          if(settings.checkOnRefresh) {
22024
            module.checkVisibility();
22025
          }
22026
          settings.onRefresh.call(element);
22027
        },
22028
22029
        resetFixed: function () {
22030
          module.remove.fixed();
22031
          module.remove.occurred();
22032
        },
22033
22034
        reset: function() {
22035
          module.verbose('Resetting all cached values');
22036
          if( $.isPlainObject(module.cache) ) {
22037
            module.cache.screen = {};
22038
            module.cache.element = {};
22039
          }
22040
        },
22041
22042
        checkVisibility: function(scroll) {
22043
          module.verbose('Checking visibility of element', module.cache.element);
22044
22045
          if( !disabled && module.is.visible() ) {
22046
22047
            // save scroll position
22048
            module.save.scroll(scroll);
22049
22050
            // update calculations derived from scroll
22051
            module.save.calculations();
22052
22053
            // percentage
22054
            module.passed();
22055
22056
            // reverse (must be first)
22057
            module.passingReverse();
22058
            module.topVisibleReverse();
22059
            module.bottomVisibleReverse();
22060
            module.topPassedReverse();
22061
            module.bottomPassedReverse();
22062
22063
            // one time
22064
            module.onScreen();
22065
            module.offScreen();
22066
            module.passing();
22067
            module.topVisible();
22068
            module.bottomVisible();
22069
            module.topPassed();
22070
            module.bottomPassed();
22071
22072
            // on update callback
22073
            if(settings.onUpdate) {
22074
              settings.onUpdate.call(element, module.get.elementCalculations());
22075
            }
22076
          }
22077
        },
22078
22079
        passed: function(amount, newCallback) {
22080
          var
22081
            calculations   = module.get.elementCalculations(),
22082
            amountInPixels
0 ignored issues
show
Unused Code introduced by
The variable amountInPixels seems to be never used. Consider removing it.
Loading history...
22083
          ;
22084
          // assign callback
22085
          if(amount && newCallback) {
22086
            settings.onPassed[amount] = newCallback;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
22087
          }
22088
          else if(amount !== undefined) {
22089
            return (module.get.pixelsPassed(amount) > calculations.pixelsPassed);
22090
          }
22091
          else if(calculations.passing) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if calculations.passing is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22092
            $.each(settings.onPassed, function(amount, callback) {
22093
              if(calculations.bottomVisible || calculations.pixelsPassed > module.get.pixelsPassed(amount)) {
22094
                module.execute(callback, amount);
22095
              }
22096
              else if(!settings.once) {
22097
                module.remove.occurred(callback);
22098
              }
22099
            });
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
22100
          }
22101
        },
22102
22103
        onScreen: function(newCallback) {
22104
          var
22105
            calculations = module.get.elementCalculations(),
22106
            callback     = newCallback || settings.onOnScreen,
22107
            callbackName = 'onScreen'
22108
          ;
22109
          if(newCallback) {
22110
            module.debug('Adding callback for onScreen', newCallback);
22111
            settings.onOnScreen = newCallback;
22112
          }
22113
          if(calculations.onScreen) {
22114
            module.execute(callback, callbackName);
22115
          }
22116
          else if(!settings.once) {
22117
            module.remove.occurred(callbackName);
22118
          }
22119
          if(newCallback !== undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback !== undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22120
            return calculations.onOnScreen;
22121
          }
22122
        },
22123
22124
        offScreen: function(newCallback) {
22125
          var
22126
            calculations = module.get.elementCalculations(),
22127
            callback     = newCallback || settings.onOffScreen,
22128
            callbackName = 'offScreen'
22129
          ;
22130
          if(newCallback) {
22131
            module.debug('Adding callback for offScreen', newCallback);
22132
            settings.onOffScreen = newCallback;
22133
          }
22134
          if(calculations.offScreen) {
22135
            module.execute(callback, callbackName);
22136
          }
22137
          else if(!settings.once) {
22138
            module.remove.occurred(callbackName);
22139
          }
22140
          if(newCallback !== undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback !== undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22141
            return calculations.onOffScreen;
22142
          }
22143
        },
22144
22145
        passing: function(newCallback) {
22146
          var
22147
            calculations = module.get.elementCalculations(),
22148
            callback     = newCallback || settings.onPassing,
22149
            callbackName = 'passing'
22150
          ;
22151
          if(newCallback) {
22152
            module.debug('Adding callback for passing', newCallback);
22153
            settings.onPassing = newCallback;
22154
          }
22155
          if(calculations.passing) {
22156
            module.execute(callback, callbackName);
22157
          }
22158
          else if(!settings.once) {
22159
            module.remove.occurred(callbackName);
22160
          }
22161
          if(newCallback !== undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback !== undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22162
            return calculations.passing;
22163
          }
22164
        },
22165
22166
22167
        topVisible: function(newCallback) {
22168
          var
22169
            calculations = module.get.elementCalculations(),
22170
            callback     = newCallback || settings.onTopVisible,
22171
            callbackName = 'topVisible'
22172
          ;
22173
          if(newCallback) {
22174
            module.debug('Adding callback for top visible', newCallback);
22175
            settings.onTopVisible = newCallback;
22176
          }
22177
          if(calculations.topVisible) {
22178
            module.execute(callback, callbackName);
22179
          }
22180
          else if(!settings.once) {
22181
            module.remove.occurred(callbackName);
22182
          }
22183
          if(newCallback === undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback === undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22184
            return calculations.topVisible;
22185
          }
22186
        },
22187
22188
        bottomVisible: function(newCallback) {
22189
          var
22190
            calculations = module.get.elementCalculations(),
22191
            callback     = newCallback || settings.onBottomVisible,
22192
            callbackName = 'bottomVisible'
22193
          ;
22194
          if(newCallback) {
22195
            module.debug('Adding callback for bottom visible', newCallback);
22196
            settings.onBottomVisible = newCallback;
22197
          }
22198
          if(calculations.bottomVisible) {
22199
            module.execute(callback, callbackName);
22200
          }
22201
          else if(!settings.once) {
22202
            module.remove.occurred(callbackName);
22203
          }
22204
          if(newCallback === undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback === undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22205
            return calculations.bottomVisible;
22206
          }
22207
        },
22208
22209
        topPassed: function(newCallback) {
22210
          var
22211
            calculations = module.get.elementCalculations(),
22212
            callback     = newCallback || settings.onTopPassed,
22213
            callbackName = 'topPassed'
22214
          ;
22215
          if(newCallback) {
22216
            module.debug('Adding callback for top passed', newCallback);
22217
            settings.onTopPassed = newCallback;
22218
          }
22219
          if(calculations.topPassed) {
22220
            module.execute(callback, callbackName);
22221
          }
22222
          else if(!settings.once) {
22223
            module.remove.occurred(callbackName);
22224
          }
22225
          if(newCallback === undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback === undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22226
            return calculations.topPassed;
22227
          }
22228
        },
22229
22230
        bottomPassed: function(newCallback) {
22231
          var
22232
            calculations = module.get.elementCalculations(),
22233
            callback     = newCallback || settings.onBottomPassed,
22234
            callbackName = 'bottomPassed'
22235
          ;
22236
          if(newCallback) {
22237
            module.debug('Adding callback for bottom passed', newCallback);
22238
            settings.onBottomPassed = newCallback;
22239
          }
22240
          if(calculations.bottomPassed) {
22241
            module.execute(callback, callbackName);
22242
          }
22243
          else if(!settings.once) {
22244
            module.remove.occurred(callbackName);
22245
          }
22246
          if(newCallback === undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback === undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22247
            return calculations.bottomPassed;
22248
          }
22249
        },
22250
22251
        passingReverse: function(newCallback) {
22252
          var
22253
            calculations = module.get.elementCalculations(),
22254
            callback     = newCallback || settings.onPassingReverse,
22255
            callbackName = 'passingReverse'
22256
          ;
22257
          if(newCallback) {
22258
            module.debug('Adding callback for passing reverse', newCallback);
22259
            settings.onPassingReverse = newCallback;
22260
          }
22261
          if(!calculations.passing) {
22262
            if(module.get.occurred('passing')) {
22263
              module.execute(callback, callbackName);
22264
            }
22265
          }
22266
          else if(!settings.once) {
22267
            module.remove.occurred(callbackName);
22268
          }
22269
          if(newCallback !== undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback !== undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22270
            return !calculations.passing;
22271
          }
22272
        },
22273
22274
22275
        topVisibleReverse: function(newCallback) {
22276
          var
22277
            calculations = module.get.elementCalculations(),
22278
            callback     = newCallback || settings.onTopVisibleReverse,
22279
            callbackName = 'topVisibleReverse'
22280
          ;
22281
          if(newCallback) {
22282
            module.debug('Adding callback for top visible reverse', newCallback);
22283
            settings.onTopVisibleReverse = newCallback;
22284
          }
22285
          if(!calculations.topVisible) {
22286
            if(module.get.occurred('topVisible')) {
22287
              module.execute(callback, callbackName);
22288
            }
22289
          }
22290
          else if(!settings.once) {
22291
            module.remove.occurred(callbackName);
22292
          }
22293
          if(newCallback === undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback === undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22294
            return !calculations.topVisible;
22295
          }
22296
        },
22297
22298
        bottomVisibleReverse: function(newCallback) {
22299
          var
22300
            calculations = module.get.elementCalculations(),
22301
            callback     = newCallback || settings.onBottomVisibleReverse,
22302
            callbackName = 'bottomVisibleReverse'
22303
          ;
22304
          if(newCallback) {
22305
            module.debug('Adding callback for bottom visible reverse', newCallback);
22306
            settings.onBottomVisibleReverse = newCallback;
22307
          }
22308
          if(!calculations.bottomVisible) {
22309
            if(module.get.occurred('bottomVisible')) {
22310
              module.execute(callback, callbackName);
22311
            }
22312
          }
22313
          else if(!settings.once) {
22314
            module.remove.occurred(callbackName);
22315
          }
22316
          if(newCallback === undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback === undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22317
            return !calculations.bottomVisible;
22318
          }
22319
        },
22320
22321
        topPassedReverse: function(newCallback) {
22322
          var
22323
            calculations = module.get.elementCalculations(),
22324
            callback     = newCallback || settings.onTopPassedReverse,
22325
            callbackName = 'topPassedReverse'
22326
          ;
22327
          if(newCallback) {
22328
            module.debug('Adding callback for top passed reverse', newCallback);
22329
            settings.onTopPassedReverse = newCallback;
22330
          }
22331
          if(!calculations.topPassed) {
22332
            if(module.get.occurred('topPassed')) {
22333
              module.execute(callback, callbackName);
22334
            }
22335
          }
22336
          else if(!settings.once) {
22337
            module.remove.occurred(callbackName);
22338
          }
22339
          if(newCallback === undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback === undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22340
            return !calculations.onTopPassed;
22341
          }
22342
        },
22343
22344
        bottomPassedReverse: function(newCallback) {
22345
          var
22346
            calculations = module.get.elementCalculations(),
22347
            callback     = newCallback || settings.onBottomPassedReverse,
22348
            callbackName = 'bottomPassedReverse'
22349
          ;
22350
          if(newCallback) {
22351
            module.debug('Adding callback for bottom passed reverse', newCallback);
22352
            settings.onBottomPassedReverse = newCallback;
22353
          }
22354
          if(!calculations.bottomPassed) {
22355
            if(module.get.occurred('bottomPassed')) {
22356
              module.execute(callback, callbackName);
22357
            }
22358
          }
22359
          else if(!settings.once) {
22360
            module.remove.occurred(callbackName);
22361
          }
22362
          if(newCallback === undefined) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if newCallback === undefined is false. Are you sure this is correct? If so, consider adding return; explicitly.

This check looks for functions where a return statement is found in some execution paths, but not in all.

Consider this little piece of code

function isBig(a) {
    if (a > 5000) {
        return "yes";
    }
}

console.log(isBig(5001)); //returns yes
console.log(isBig(42)); //returns undefined

The function isBig will only return a specific value when its parameter is bigger than 5000. In any other case, it will implicitly return undefined.

This behaviour may not be what you had intended. In any case, you can add a return undefined to the other execution path to make the return value explicit.

Loading history...
22363
            return !calculations.bottomPassed;
22364
          }
22365
        },
22366
22367
        execute: function(callback, callbackName) {
22368
          var
22369
            calculations = module.get.elementCalculations(),
22370
            screen       = module.get.screenCalculations()
22371
          ;
22372
          callback = callback || false;
22373
          if(callback) {
22374
            if(settings.continuous) {
22375
              module.debug('Callback being called continuously', callbackName, calculations);
22376
              callback.call(element, calculations, screen);
22377
            }
22378
            else if(!module.get.occurred(callbackName)) {
22379
              module.debug('Conditions met', callbackName, calculations);
22380
              callback.call(element, calculations, screen);
22381
            }
22382
          }
22383
          module.save.occurred(callbackName);
22384
        },
22385
22386
        remove: {
22387
          fixed: function() {
22388
            module.debug('Removing fixed position');
22389
            $module
22390
              .removeClass(className.fixed)
22391
              .css({
22392
                position : '',
22393
                top      : '',
22394
                left     : '',
22395
                zIndex   : ''
22396
              })
22397
            ;
22398
            settings.onUnfixed.call(element);
22399
          },
22400
          placeholder: function() {
22401
            module.debug('Removing placeholder content');
22402
            if($placeholder) {
22403
              $placeholder.remove();
22404
            }
22405
          },
22406
          occurred: function(callback) {
22407
            if(callback) {
22408
              var
22409
                occurred = module.cache.occurred
22410
              ;
22411
              if(occurred[callback] !== undefined && occurred[callback] === true) {
22412
                module.debug('Callback can now be called again', callback);
22413
                module.cache.occurred[callback] = false;
22414
              }
22415
            }
22416
            else {
22417
              module.cache.occurred = {};
22418
            }
22419
          }
22420
        },
22421
22422
        save: {
22423
          calculations: function() {
22424
            module.verbose('Saving all calculations necessary to determine positioning');
22425
            module.save.direction();
22426
            module.save.screenCalculations();
22427
            module.save.elementCalculations();
22428
          },
22429
          occurred: function(callback) {
22430
            if(callback) {
22431
              if(module.cache.occurred[callback] === undefined || (module.cache.occurred[callback] !== true)) {
22432
                module.verbose('Saving callback occurred', callback);
22433
                module.cache.occurred[callback] = true;
22434
              }
22435
            }
22436
          },
22437
          scroll: function(scrollPosition) {
22438
            scrollPosition      = scrollPosition + settings.offset || $context.scrollTop() + settings.offset;
22439
            module.cache.scroll = scrollPosition;
22440
          },
22441
          direction: function() {
22442
            var
22443
              scroll     = module.get.scroll(),
22444
              lastScroll = module.get.lastScroll(),
22445
              direction
22446
            ;
22447
            if(scroll > lastScroll && lastScroll) {
22448
              direction = 'down';
22449
            }
22450
            else if(scroll < lastScroll && lastScroll) {
22451
              direction = 'up';
22452
            }
22453
            else {
22454
              direction = 'static';
22455
            }
22456
            module.cache.direction = direction;
22457
            return module.cache.direction;
22458
          },
22459
          elementPosition: function() {
22460
            var
22461
              element = module.cache.element,
22462
              screen  = module.get.screenSize()
22463
            ;
22464
            module.verbose('Saving element position');
22465
            // (quicker than $.extend)
22466
            element.fits          = (element.height < screen.height);
22467
            element.offset        = $module.offset();
22468
            element.width         = $module.outerWidth();
22469
            element.height        = $module.outerHeight();
22470
            // compensate for scroll in context
22471
            if(module.is.verticallyScrollableContext()) {
22472
              element.offset.top += $context.scrollTop() - $context.offset().top;
22473
            }
22474
            if(module.is.horizontallyScrollableContext()) {
22475
              element.offset.left += $context.scrollLeft - $context.offset().left;
22476
            }
22477
            // store
22478
            module.cache.element = element;
22479
            return element;
22480
          },
22481
          elementCalculations: function() {
22482
            var
22483
              screen     = module.get.screenCalculations(),
22484
              element    = module.get.elementPosition()
22485
            ;
22486
            // offset
22487
            if(settings.includeMargin) {
22488
              element.margin        = {};
22489
              element.margin.top    = parseInt($module.css('margin-top'), 10);
22490
              element.margin.bottom = parseInt($module.css('margin-bottom'), 10);
22491
              element.top    = element.offset.top - element.margin.top;
22492
              element.bottom = element.offset.top + element.height + element.margin.bottom;
22493
            }
22494
            else {
22495
              element.top    = element.offset.top;
22496
              element.bottom = element.offset.top + element.height;
22497
            }
22498
22499
            // visibility
22500
            element.topPassed        = (screen.top >= element.top);
22501
            element.bottomPassed     = (screen.top >= element.bottom);
22502
            element.topVisible       = (screen.bottom >= element.top) && !element.bottomPassed;
22503
            element.bottomVisible    = (screen.bottom >= element.bottom) && !element.topPassed;
22504
            element.pixelsPassed     = 0;
22505
            element.percentagePassed = 0;
22506
22507
            // meta calculations
22508
            element.onScreen  = (element.topVisible && !element.bottomPassed);
22509
            element.passing   = (element.topPassed && !element.bottomPassed);
22510
            element.offScreen = (!element.onScreen);
22511
22512
            // passing calculations
22513
            if(element.passing) {
22514
              element.pixelsPassed     = (screen.top - element.top);
22515
              element.percentagePassed = (screen.top - element.top) / element.height;
22516
            }
22517
            module.cache.element = element;
22518
            module.verbose('Updated element calculations', element);
22519
            return element;
22520
          },
22521
          screenCalculations: function() {
22522
            var
22523
              scroll = module.get.scroll()
22524
            ;
22525
            module.save.direction();
22526
            module.cache.screen.top    = scroll;
22527
            module.cache.screen.bottom = scroll + module.cache.screen.height;
22528
            return module.cache.screen;
22529
          },
22530
          screenSize: function() {
22531
            module.verbose('Saving window position');
22532
            module.cache.screen = {
22533
              height: $context.height()
22534
            };
22535
          },
22536
          position: function() {
22537
            module.save.screenSize();
22538
            module.save.elementPosition();
22539
          }
22540
        },
22541
22542
        get: {
22543
          pixelsPassed: function(amount) {
22544
            var
22545
              element = module.get.elementCalculations()
22546
            ;
22547
            if(amount.search('%') > -1) {
22548
              return ( element.height * (parseInt(amount, 10) / 100) );
22549
            }
22550
            return parseInt(amount, 10);
22551
          },
22552
          occurred: function(callback) {
22553
            return (module.cache.occurred !== undefined)
22554
              ? module.cache.occurred[callback] || false
22555
              : false
22556
            ;
22557
          },
22558
          direction: function() {
22559
            if(module.cache.direction === undefined) {
22560
              module.save.direction();
22561
            }
22562
            return module.cache.direction;
22563
          },
22564
          elementPosition: function() {
22565
            if(module.cache.element === undefined) {
22566
              module.save.elementPosition();
22567
            }
22568
            return module.cache.element;
22569
          },
22570
          elementCalculations: function() {
22571
            if(module.cache.element === undefined) {
22572
              module.save.elementCalculations();
22573
            }
22574
            return module.cache.element;
22575
          },
22576
          screenCalculations: function() {
22577
            if(module.cache.screen === undefined) {
22578
              module.save.screenCalculations();
22579
            }
22580
            return module.cache.screen;
22581
          },
22582
          screenSize: function() {
22583
            if(module.cache.screen === undefined) {
22584
              module.save.screenSize();
22585
            }
22586
            return module.cache.screen;
22587
          },
22588
          scroll: function() {
22589
            if(module.cache.scroll === undefined) {
22590
              module.save.scroll();
22591
            }
22592
            return module.cache.scroll;
22593
          },
22594
          lastScroll: function() {
22595
            if(module.cache.screen === undefined) {
22596
              module.debug('First scroll event, no last scroll could be found');
22597
              return false;
22598
            }
22599
            return module.cache.screen.top;
22600
          }
22601
        },
22602
22603
        setting: function(name, value) {
22604
          if( $.isPlainObject(name) ) {
22605
            $.extend(true, settings, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
22606
          }
22607
          else if(value !== undefined) {
22608
            settings[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
22609
          }
22610
          else {
22611
            return settings[name];
22612
          }
22613
        },
22614
        internal: function(name, value) {
22615
          if( $.isPlainObject(name) ) {
22616
            $.extend(true, module, name);
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
22617
          }
22618
          else if(value !== undefined) {
22619
            module[name] = value;
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
22620
          }
22621
          else {
22622
            return module[name];
22623
          }
22624
        },
22625
        debug: function() {
22626
          if(!settings.silent && settings.debug) {
22627
            if(settings.performance) {
22628
              module.performance.log(arguments);
22629
            }
22630
            else {
22631
              module.debug = Function.prototype.bind.call(console.info, console, settings.name + ':');
22632
              module.debug.apply(console, arguments);
22633
            }
22634
          }
22635
        },
22636
        verbose: function() {
22637
          if(!settings.silent && settings.verbose && settings.debug) {
22638
            if(settings.performance) {
22639
              module.performance.log(arguments);
22640
            }
22641
            else {
22642
              module.verbose = Function.prototype.bind.call(console.info, console, settings.name + ':');
22643
              module.verbose.apply(console, arguments);
22644
            }
22645
          }
22646
        },
22647
        error: function() {
22648
          if(!settings.silent) {
22649
            module.error = Function.prototype.bind.call(console.error, console, settings.name + ':');
22650
            module.error.apply(console, arguments);
22651
          }
22652
        },
22653
        performance: {
22654
          log: function(message) {
22655
            var
22656
              currentTime,
22657
              executionTime,
22658
              previousTime
22659
            ;
22660
            if(settings.performance) {
22661
              currentTime   = new Date().getTime();
22662
              previousTime  = time || currentTime;
22663
              executionTime = currentTime - previousTime;
22664
              time          = currentTime;
22665
              performance.push({
22666
                'Name'           : message[0],
22667
                'Arguments'      : [].slice.call(message, 1) || '',
22668
                'Element'        : element,
22669
                'Execution Time' : executionTime
22670
              });
22671
            }
22672
            clearTimeout(module.performance.timer);
22673
            module.performance.timer = setTimeout(module.performance.display, 500);
22674
          },
22675
          display: function() {
22676
            var
22677
              title = settings.name + ':',
22678
              totalTime = 0
22679
            ;
22680
            time = false;
22681
            clearTimeout(module.performance.timer);
22682
            $.each(performance, function(index, data) {
22683
              totalTime += data['Execution Time'];
22684
            });
22685
            title += ' ' + totalTime + 'ms';
22686
            if(moduleSelector) {
22687
              title += ' \'' + moduleSelector + '\'';
22688
            }
22689
            if( (console.group !== undefined || console.table !== undefined) && performance.length > 0) {
22690
              console.groupCollapsed(title);
22691
              if(console.table) {
22692
                console.table(performance);
22693
              }
22694
              else {
22695
                $.each(performance, function(index, data) {
22696
                  console.log(data['Name'] + ': ' + data['Execution Time']+'ms');
0 ignored issues
show
Debugging Code introduced by
console.log looks like debug code. Are you sure you do not want to remove it?
Loading history...
22697
                });
22698
              }
22699
              console.groupEnd();
22700
            }
22701
            performance = [];
22702
          }
22703
        },
22704
        invoke: function(query, passedArguments, context) {
22705
          var
22706
            object = instance,
22707
            maxDepth,
22708
            found,
22709
            response
22710
          ;
22711
          passedArguments = passedArguments || queryArguments;
22712
          context         = element         || context;
22713
          if(typeof query == 'string' && object !== undefined) {
22714
            query    = query.split(/[\. ]/);
22715
            maxDepth = query.length - 1;
22716
            $.each(query, function(depth, value) {
22717
              var camelCaseValue = (depth != maxDepth)
22718
                ? value + query[depth + 1].charAt(0).toUpperCase() + query[depth + 1].slice(1)
22719
                : query
22720
              ;
22721
              if( $.isPlainObject( object[camelCaseValue] ) && (depth != maxDepth) ) {
22722
                object = object[camelCaseValue];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
22723
              }
22724
              else if( object[camelCaseValue] !== undefined ) {
22725
                found = object[camelCaseValue];
22726
                return false;
22727
              }
22728
              else if( $.isPlainObject( object[value] ) && (depth != maxDepth) ) {
22729
                object = object[value];
0 ignored issues
show
Best Practice introduced by
There is no return statement in this branch, but you do return something in other branches. Did you maybe miss it? If you do not want to return anything, consider adding return undefined; explicitly.
Loading history...
22730
              }
22731
              else if( object[value] !== undefined ) {
22732
                found = object[value];
22733
                return false;
22734
              }
22735
              else {
22736
                module.error(error.method, query);
22737
                return false;
22738
              }
22739
            });
22740
          }
22741
          if ( $.isFunction( found ) ) {
22742
            response = found.apply(context, passedArguments);
22743
          }
22744
          else if(found !== undefined) {
22745
            response = found;
22746
          }
22747
          if($.isArray(returnedValue)) {
22748
            returnedValue.push(response);
0 ignored issues
show
Bug introduced by
The variable response does not seem to be initialized in case found !== undefined on line 22744 is false. Are you sure the function push handles undefined variables?
Loading history...
22749
          }
22750
          else if(returnedValue !== undefined) {
22751
            returnedValue = [returnedValue, response];
22752
          }
22753
          else if(response !== undefined) {
22754
            returnedValue = response;
22755
          }
22756
          return found;
22757
        }
22758
      };
22759
22760
      if(methodInvoked) {
22761
        if(instance === undefined) {
22762
          module.initialize();
22763
        }
22764
        instance.save.scroll();
22765
        instance.save.calculations();
22766
        module.invoke(query);
22767
      }
22768
      else {
22769
        if(instance !== undefined) {
22770
          instance.invoke('destroy');
22771
        }
22772
        module.initialize();
22773
      }
22774
    })
22775
  ;
22776
22777
  return (returnedValue !== undefined)
22778
    ? returnedValue
22779
    : this
22780
  ;
22781
};
22782
22783
$.fn.visibility.settings = {
22784
22785
  name                   : 'Visibility',
22786
  namespace              : 'visibility',
22787
22788
  debug                  : false,
22789
  verbose                : false,
22790
  performance            : true,
22791
22792
  // whether to use mutation observers to follow changes
22793
  observeChanges         : true,
22794
22795
  // check position immediately on init
22796
  initialCheck           : true,
22797
22798
  // whether to refresh calculations after all page images load
22799
  refreshOnLoad          : true,
22800
22801
  // whether to refresh calculations after page resize event
22802
  refreshOnResize        : true,
22803
22804
  // should call callbacks on refresh event (resize, etc)
22805
  checkOnRefresh         : true,
22806
22807
  // callback should only occur one time
22808
  once                   : true,
22809
22810
  // callback should fire continuously whe evaluates to true
22811
  continuous             : false,
22812
22813
  // offset to use with scroll top
22814
  offset                 : 0,
22815
22816
  // whether to include margin in elements position
22817
  includeMargin          : false,
22818
22819
  // scroll context for visibility checks
22820
  context                : window,
22821
22822
  // visibility check delay in ms (defaults to animationFrame)
22823
  throttle               : false,
22824
22825
  // special visibility type (image, fixed)
22826
  type                   : false,
22827
22828
  // z-index to use with visibility 'fixed'
22829
  zIndex                 : '10',
22830
22831
  // image only animation settings
22832
  transition             : 'fade in',
22833
  duration               : 1000,
22834
22835
  // array of callbacks for percentage
22836
  onPassed               : {},
22837
22838
  // standard callbacks
22839
  onOnScreen             : false,
22840
  onOffScreen            : false,
22841
  onPassing              : false,
22842
  onTopVisible           : false,
22843
  onBottomVisible        : false,
22844
  onTopPassed            : false,
22845
  onBottomPassed         : false,
22846
22847
  // reverse callbacks
22848
  onPassingReverse       : false,
22849
  onTopVisibleReverse    : false,
22850
  onBottomVisibleReverse : false,
22851
  onTopPassedReverse     : false,
22852
  onBottomPassedReverse  : false,
22853
22854
  // special callbacks for image
22855
  onLoad                 : function() {},
22856
  onAllLoaded            : function() {},
22857
22858
  // special callbacks for fixed position
22859
  onFixed                : function() {},
22860
  onUnfixed              : function() {},
22861
22862
  // utility callbacks
22863
  onUpdate               : false, // disabled by default for performance
22864
  onRefresh              : function(){},
22865
22866
  metadata : {
22867
    src: 'src'
22868
  },
22869
22870
  className: {
22871
    fixed       : 'fixed',
22872
    placeholder : 'placeholder',
22873
    visible     : 'visible'
22874
  },
22875
22876
  error : {
22877
    method  : 'The method you called is not defined.',
22878
    visible : 'Element is hidden, you must call refresh after element becomes visible'
22879
  }
22880
22881
};
22882
22883
})( jQuery, window, document );
22884