Completed
Pull Request — master (#3325)
by Emanuele
11:19
created

themes/default/scripts/elk_jquery_plugins.js   F

Complexity

Total Complexity 129
Complexity/F 1.77

Size

Lines of Code 691
Function Count 73

Duplication

Duplicated Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 438
dl 0
loc 691
rs 2
c 0
b 0
f 0
wmc 129
mnd 56
bc 56
fnc 73
bpm 0.7671
cpm 1.7671
noi 21

How to fix   Complexity   

Complexity

Complex classes like themes/default/scripts/elk_jquery_plugins.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
 * @name      ElkArte Forum
3
 * @copyright ElkArte Forum contributors
4
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause
5
 *
6
 * @version 1.1
7
 *
8
 * This file contains javascript plugins for use with jquery
9
 */
10
11
/*!
12
 * hoverIntent v1.9.0 // 2014.08.11 // jQuery v1.9.1+
13
 * http://cherne.net/brian/resources/jquery.hoverIntent.html
14
 *
15
 * You may use hoverIntent under the terms of the MIT license. Basically that
16
 * means you are free to use hoverIntent as long as this header is left intact.
17
 * Copyright 2007, 2014 Brian Cherne
18
 */
19
20
/* hoverIntent is similar to jQuery's built-in "hover" method except that
21
 * instead of firing the handlerIn function immediately, hoverIntent checks
22
 * to see if the user's mouse has slowed down (beneath the sensitivity
23
 * threshold) before firing the event. The handlerOut function is only
24
 * called after a matching handlerIn.
25
 *
26
 * // basic usage ... just like .hover()
27
 * .hoverIntent( handlerIn, handlerOut )
28
 * .hoverIntent( handlerInOut )
29
 *
30
 * // basic usage ... with event delegation!
31
 * .hoverIntent( handlerIn, handlerOut, selector )
32
 * .hoverIntent( handlerInOut, selector )
33
 *
34
 * // using a basic configuration object
35
 * .hoverIntent( config )
36
 *
37
 * @param  handlerIn   function OR configuration object
38
 * @param  handlerOut  function OR selector for delegation OR undefined
39
 * @param  selector    selector OR undefined
40
 * @author Brian Cherne <brian(at)cherne(dot)net>
41
 */
42
43
(function(factory) {
44
	'use strict';
45
	if (typeof define === 'function' && define.amd) {
0 ignored issues
show
Bug introduced by
The variable define seems to be never declared. If this is a global, consider adding a /** global: define */ 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...
46
		define(['jquery'], factory);
47
	} else if (jQuery && !jQuery.fn.hoverIntent) {
48
		factory(jQuery);
49
	}
50
})(function($) {
51
	'use strict';
52
53
	// default configuration values
54
	var _cfg = {
55
		interval: 100,
56
		sensitivity: 6,
57
		timeout: 0
58
	};
59
60
	// counter used to generate an ID for each instance
61
	var INSTANCE_COUNT = 0;
62
63
	// current X and Y position of mouse, updated during mousemove tracking (shared across instances)
64
	var cX, cY;
65
66
	// saves the current pointer position coordinated based on the given mouse event
67
	var track = function(ev) {
68
		cX = ev.pageX;
69
		cY = ev.pageY;
70
	};
71
72
	// compares current and previous mouse positions
73
	var compare = function(ev,$el,s,cfg) {
74
		// compare mouse positions to see if pointer has slowed enough to trigger `over` function
75
		if ( Math.sqrt( (s.pX-cX)*(s.pX-cX) + (s.pY-cY)*(s.pY-cY) ) < cfg.sensitivity ) {
76
			$el.off('mousemove.hoverIntent'+s.namespace,track);
77
			delete s.timeoutId;
78
			// set hoverIntent state as active for this element (so `out` handler can eventually be called)
79
			s.isActive = true;
80
			// clear coordinate data
81
			delete s.pX; delete s.pY;
82
			return cfg.over.apply($el[0],[ev]);
83
		} 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...
84
			// set previous coordinates for next comparison
85
			s.pX = cX; s.pY = cY;
86
			// use self-calling timeout, guarantees intervals are spaced out properly (avoids JavaScript timer bugs)
87
			s.timeoutId = setTimeout( function(){compare(ev, $el, s, cfg);} , cfg.interval );
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...
88
		}
89
	};
90
91
	// triggers given `out` function at configured `timeout` after a mouseleave and clears state
92
	var delay = function(ev,$el,s,out) {
93
		delete $el.data('hoverIntent')[s.id];
94
		return out.apply($el[0],[ev]);
95
	};
96
97
	$.fn.hoverIntent = function(handlerIn,handlerOut,selector) {
98
		// instance ID, used as a key to store and retrieve state information on an element
99
		var instanceId = INSTANCE_COUNT++;
100
101
		// extend the default configuration and parse parameters
102
		var cfg = $.extend({}, _cfg);
103
		if ( $.isPlainObject(handlerIn) ) {
104
			cfg = $.extend(cfg, handlerIn );
105
		} else if ($.isFunction(handlerOut)) {
106
			cfg = $.extend(cfg, { over: handlerIn, out: handlerOut, selector: selector } );
107
		} else {
108
			cfg = $.extend(cfg, { over: handlerIn, out: handlerIn, selector: handlerOut } );
109
		}
110
111
		// A private function for handling mouse 'hovering'
112
		var handleHover = function(e) {
113
			// cloned event to pass to handlers (copy required for event object to be passed in IE)
114
			var ev = $.extend({},e);
115
116
			// the current target of the mouse event, wrapped in a jQuery object
117
			var $el = $(this);
118
119
			// read hoverIntent data from element (or initialize if not present)
120
			var hoverIntentData = $el.data('hoverIntent');
121
			if (!hoverIntentData) { $el.data('hoverIntent', (hoverIntentData = {})); }
122
123
			// read per-instance state from element (or initialize if not present)
124
			var state = hoverIntentData[instanceId];
125
			if (!state) { hoverIntentData[instanceId] = state = { id: instanceId }; }
126
127
			// state properties:
128
			// id = instance ID, used to clean up data
129
			// timeoutId = timeout ID, reused for tracking mouse position and delaying "out" handler
130
			// isActive = plugin state, true after `over` is called just until `out` is called
131
			// pX, pY = previously-measured pointer coordinates, updated at each polling interval
132
			// namespace = string used as namespace for per-instance event management
133
134
			// clear any existing timeout
135
			if (state.timeoutId) { state.timeoutId = clearTimeout(state.timeoutId); }
136
137
			// event namespace, used to register and unregister mousemove tracking
138
			var namespace = state.namespace = '.hoverIntent'+instanceId;
139
140
			// handle the event, based on its type
141
			if (e.type === 'mouseenter') {
142
				// do nothing if already active
143
				if (state.isActive) { return; }
144
				// set "previous" X and Y position based on initial entry point
145
				state.pX = ev.pageX; state.pY = ev.pageY;
146
				// update "current" X and Y position based on mousemove
147
				$el.on('mousemove.hoverIntent'+namespace,track);
148
				// start polling interval (self-calling timeout) to compare mouse coordinates over time
149
				state.timeoutId = setTimeout( function(){compare(ev,$el,state,cfg);} , cfg.interval );
150
			} else { // "mouseleave"
151
				// do nothing if not already active
152
				if (!state.isActive) { return; }
153
				// unbind expensive mousemove event
154
				$el.off('mousemove.hoverIntent'+namespace,track);
155
				// if hoverIntent state is true, then call the mouseOut function after the specified delay
156
				state.timeoutId = setTimeout( function(){delay(ev,$el,state,cfg.out);} , cfg.timeout );
157
			}
158
		};
159
160
		// listen for mouseenter and mouseleave
161
		return this.on({'mouseenter.hoverIntent':handleHover,'mouseleave.hoverIntent':handleHover}, cfg.selector);
162
	};
163
});
164
165
166
167
/*
168
 * jQuery Superfish Menu Plugin 1.7.9
169
 * Copyright (c) 2013 Joel Birch
170
 *
171
 * Dual licensed under the MIT and GPL licenses:
172
 *	http://www.opensource.org/licenses/mit-license.php
173
 *	http://www.gnu.org/licenses/gpl.html
174
 */
175
176
(function ($, w) {
177
	"use strict";
178
179
	var methods = (function () {
180
		// private properties and methods go here
181
		var c = {
182
				bcClass: 'sf-breadcrumb',
183
				menuClass: 'sf-js-enabled',
184
				anchorClass: 'sf-with-ul',
185
				menuArrowClass: 'sf-arrows'
186
			},
187
			outerClick = (function() {
0 ignored issues
show
Unused Code introduced by
The variable outerClick seems to be never used. Consider removing it.
Loading history...
188
				$(window).on('load', function() {
189
					$('body').children().on('click.superfish', function() {
190
						$('.sf-js-enabled').superfish('hide', 'true');
191
					});
192
				});
193
			})(),
194
			ios = (function () {
195
				var ios = /^(?![\w\W]*Windows Phone)[\w\W]*(iPhone|iPad|iPod)/i.test(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...
196
				if (ios) {
197
					// tap anywhere on iOS to unfocus a submenu
198
					$('html').css('cursor', 'pointer').on('click', $.noop);
199
				}
200
				return ios;
201
			})(),
202
			wp7 = (function () {
203
				var style = document.documentElement.style;
204
				return ('behavior' in style && 'fill' in style && /iemobile/i.test(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...
205
			})(),
206
			unprefixedPointerEvents = (function () {
207
				return (!!w.PointerEvent);
208
			})(),
209
			toggleMenuClasses = function ($menu, o, add) {
210
				var classes = c.menuClass,
211
					method;
212
				if (o.cssArrows) {
213
					classes += ' ' + c.menuArrowClass;
214
				}
215
				method = (add) ? 'addClass' : 'removeClass';
216
				$menu[method](classes);
217
			},
218
			setPathToCurrent = function ($menu, o) {
219
				return $menu.find('li.' + o.pathClass).slice(0, o.pathLevels)
220
					.addClass(o.hoverClass + ' ' + c.bcClass)
221
					.filter(function () {
222
						return ($(this).children(o.popUpSelector).hide().show().length);
223
					}).removeClass(o.pathClass);
224
			},
225
			toggleAnchorClass = function ($li, add) {
226
				var method = (add) ? 'addClass' : 'removeClass';
227
				$li.children('a')[method](c.anchorClass);
228
			},
229
			toggleTouchAction = function ($menu) {
230
				var msTouchAction = $menu.css('ms-touch-action');
231
				var touchAction = $menu.css('touch-action');
232
				touchAction = touchAction || msTouchAction;
233
				touchAction = (touchAction === 'pan-y') ? 'auto' : 'pan-y';
234
				$menu.css({
235
					'ms-touch-action': touchAction,
236
					'touch-action': touchAction
237
				});
238
			},
239
			getMenu = function ($el) {
240
				return $el.closest('.' + c.menuClass);
241
			},
242
			getOptions = function ($el) {
243
				return getMenu($el).data('sfOptions');
244
			},
245
			over = function () {
246
				var $this = $(this),
247
					o = getOptions($this);
248
				clearTimeout(o.sfTimer);
249
				$this.siblings().superfish('hide').end().superfish('show');
250
			},
251
			close = function (o) {
252
				o.retainPath = ($.inArray(this[0], o.$path) > -1);
253
				this.superfish('hide');
254
255
				if (!this.parents('.' + o.hoverClass).length) {
256
					o.onIdle.call(getMenu(this));
257
					if (o.$path.length) {
258
						$.proxy(over, o.$path)();
259
					}
260
				}
261
			},
262
			out = function () {
263
				var $this = $(this),
264
					o = getOptions($this);
265
				if (ios) {
266
					$.proxy(close, $this, o)();
267
				}
268
				else {
269
					clearTimeout(o.sfTimer);
270
					o.sfTimer = setTimeout($.proxy(close, $this, o), o.delay);
271
				}
272
			},
273
			touchHandler = function (e) {
274
				var $this = $(this),
275
					o = getOptions($this),
276
					$ul = $this.siblings(e.data.popUpSelector);
277
278
				if (o.onHandleTouch.call($ul) === false) {
279
					return this;
280
				}
281
282
				if ($ul.length > 0 && $ul.is(':hidden')) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if $ul.length > 0 && $ul.is(":hidden") 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...
283
					$this.one('click.superfish', false);
284
					if (e.type === 'MSPointerDown' || e.type === 'pointerdown') {
285
						$this.trigger('focus');
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...
286
					} else {
287
						$.proxy(over, $this.parent('li'))();
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...
288
					}
289
				}
290
			},
291
			applyHandlers = function ($menu, o) {
292
				var targets = 'li:has(' + o.popUpSelector + ')';
293
				if ($.fn.hoverIntent && !o.disableHI) {
294
					$menu.hoverIntent(over, out, targets);
295
				}
296
				else {
297
					$menu
298
						.on('mouseenter.superfish', targets, over)
299
						.on('mouseleave.superfish', targets, out);
300
				}
301
				var touchevent = 'MSPointerDown.superfish';
302
				if (unprefixedPointerEvents) {
303
					touchevent = 'pointerdown.superfish';
304
				}
305
				if (!ios) {
306
					touchevent += ' touchend.superfish';
307
				}
308
				if (wp7) {
309
					touchevent += ' mousedown.superfish';
310
				}
311
				$menu
312
					.on('focusin.superfish', 'li', over)
313
					.on('focusout.superfish', 'li', out)
314
					.on(touchevent, 'a', o, touchHandler);
315
			};
316
317
		return {
318
			// public methods
319
			hide: function (instant) {
320
				if (this.length) {
321
					var $this = this,
322
						o = getOptions($this);
323
					if (!o) {
324
						return this;
325
					}
326
					var not = (o.retainPath === true) ? o.$path : '',
327
						$ul = $this.find('li.' + o.hoverClass).add(this).not(not).removeClass(o.hoverClass).children(o.popUpSelector),
328
						speed = o.speedOut;
329
330
					if (instant) {
331
						$ul.show();
332
						speed = 0;
333
					}
334
					o.retainPath = false;
335
336
					if (o.onBeforeHide.call($ul) === false) {
337
						return this;
338
					}
339
340
					$ul.stop(true, true).animate(o.animationOut, speed, function () {
341
						var $this = $(this);
342
						o.onHide.call($this);
343
					});
344
				}
345
				return this;
346
			},
347
			show: function () {
348
				var o = getOptions(this);
349
				if (!o) {
350
					return this;
351
				}
352
				var $this = this.addClass(o.hoverClass),
353
					$ul = $this.children(o.popUpSelector);
354
355
				if (o.onBeforeShow.call($ul) === false) {
356
					return this;
357
				}
358
359
				$ul.stop(true, true).animate(o.animation, o.speed, function () {
360
					o.onShow.call($ul);
361
				});
362
				return this;
363
			},
364
			destroy: function () {
365
				return this.each(function () {
366
					var $this = $(this),
367
						o = $this.data('sfOptions'),
368
						$hasPopUp;
369
					if (!o) {
370
						return false;
371
					}
372
					$hasPopUp = $this.find(o.popUpSelector).parent('li');
373
					clearTimeout(o.sfTimer);
374
					toggleMenuClasses($this, o);
375
					toggleAnchorClass($hasPopUp);
376
					toggleTouchAction($this);
377
					// remove event handlers
378
					$this.off('.superfish').off('.hoverIntent');
379
					// clear animation's inline display style
380
					$hasPopUp.children(o.popUpSelector).attr('style', function (i, style) {
381
						return style.replace(/display[^;]+;?/g, '');
382
					});
383
					// reset 'current' path classes
384
					o.$path.removeClass(o.hoverClass + ' ' + c.bcClass).addClass(o.pathClass);
385
					$this.find('.' + o.hoverClass).removeClass(o.hoverClass);
386
					o.onDestroy.call($this);
387
					$this.removeData('sfOptions');
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...
388
				});
389
			},
390
			init: function (op) {
391
				return this.each(function () {
392
					var $this = $(this);
393
					if ($this.data('sfOptions')) {
394
						return false;
395
					}
396
					var o = $.extend({}, $.fn.superfish.defaults, op),
397
						$hasPopUp = $this.find(o.popUpSelector).parent('li');
398
					o.$path = setPathToCurrent($this, o);
399
400
					$this.data('sfOptions', o);
401
402
					toggleMenuClasses($this, o, true);
403
					toggleAnchorClass($hasPopUp, true);
404
					toggleTouchAction($this);
405
					applyHandlers($this, o);
406
407
					$hasPopUp.not('.' + c.bcClass).superfish('hide', true);
408
409
					o.onInit.call(this);
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...
410
				});
411
			}
412
		};
413
	})();
414
415
	$.fn.superfish = function (method, args) {
0 ignored issues
show
Unused Code introduced by
The parameter args 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...
416
		if (methods[method]) {
417
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
418
		}
419
		else if (typeof method === 'object' || ! method) {
420
			return methods.init.apply(this, arguments);
421
		}
422
		else {
423
			return $.error('Method ' +  method + ' does not exist on jQuery.fn.superfish');
424
		}
425
	};
426
427
	$.fn.superfish.defaults = {
428
		popUpSelector: 'ul,.sf-mega', // within menu context
429
		hoverClass: 'sfHover',
430
		pathClass: 'overrideThisToUse',
431
		pathLevels: 1,
432
		delay: 800,
433
		animation: {opacity: 'show'},
434
		animationOut: {opacity: 'hide'},
435
		speed: 'normal',
436
		speedOut: 'fast',
437
		cssArrows: true,
438
		disableHI: false,
439
		onInit: $.noop,
440
		onBeforeShow: $.noop,
441
		onShow: $.noop,
442
		onBeforeHide: $.noop,
443
		onHide: $.noop,
444
		onIdle: $.noop,
445
		onDestroy: $.noop,
446
		onHandleTouch: $.noop
447
	};
448
449
})(jQuery, window);
450
451
/*!
452
 * Superclick v1.0.0 - jQuery menu widget
453
 * Copyright (c) 2013 Joel Birch
454
 *
455
 * Dual licensed under the MIT and GPL licenses:
456
 *	http://www.opensource.org/licenses/mit-license.php
457
 *	http://www.gnu.org/licenses/gpl.html
458
 */
459
460
(function ($, w) {
461
	"use strict";
462
463
	var methods = (function () {
464
		// private properties and methods go here
465
		var c = {
466
				bcClass: 'sf-breadcrumb',
467
				menuClass: 'sf-js-enabled',
468
				anchorClass: 'sf-with-ul',
469
				menuArrowClass: 'sf-arrows'
470
			},
471
			outerClick = (function () {
0 ignored issues
show
Unused Code introduced by
The variable outerClick seems to be never used. Consider removing it.
Loading history...
472
				$(w).on('load', function () {
473
					$('body').children().on('click.superclick', function () {
474
						var $allMenus = $('.sf-js-enabled');
475
						$allMenus.superclick('reset');
476
					});
477
				});
478
			})(),
479
			toggleMenuClasses = function ($menu, o) {
480
				var classes = c.menuClass;
481
				if (o.cssArrows) {
482
					classes += ' ' + c.menuArrowClass;
483
				}
484
				$menu.toggleClass(classes);
485
			},
486
			setPathToCurrent = function ($menu, o) {
487
				return $menu.find('li.' + o.pathClass).slice(0, o.pathLevels)
488
					.addClass(o.activeClass + ' ' + c.bcClass)
489
						.filter(function () {
490
							return ($(this).children(o.popUpSelector).hide().show().length);
491
						}).removeClass(o.pathClass);
492
			},
493
			toggleAnchorClass = function ($li) {
494
				$li.children('a').toggleClass(c.anchorClass);
495
			},
496
			toggleTouchAction = function ($menu) {
497
				var msTouchAction = $menu.css('ms-touch-action');
498
				var touchAction = $menu.css('touch-action');
499
				touchAction = touchAction || msTouchAction;
500
				touchAction = (touchAction === 'pan-y') ? 'auto' : 'pan-y';
501
				$menu.css({
502
					'ms-touch-action': touchAction,
503
					'touch-action': touchAction
504
				});
505
			},
506
			clickHandler = function (e) {
507
				var $this = $(this),
508
					$popUp = $this.siblings(e.data.popUpSelector),
509
					func;
510
511
				if ($popUp.length) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if $popUp.length 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...
512
					var tmp = !$popUp.is(':hidden');
513
					func = ($popUp.is(':hidden')) ? over : out;
514
					$.proxy(func, $this.parent('li'))();
515
					return !!tmp;
516
				}
517
			},
518
			dblclickHandler = function(e) {
519
				var $this = $(this),
520
					$popUp = $this.siblings(e.data.popUpSelector),
521
					target = e.currentTarget.href;
522
523
				if ($popUp.length === 1 && target) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if $popUp.length === 1 && target 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...
524
					if ($popUp.not(':hidden'))
525
						$.proxy(out, $this.parent('li'))();
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

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

Consider:

if (a > 0)
    b = 42;

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

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

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

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

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

Loading history...
526
					window.location = target;
527
					return false;
528
				}
529
			},
530
			over = function () {
531
				var $this = $(this),
532
					o = getOptions($this);
0 ignored issues
show
Unused Code introduced by
The variable o seems to be never used. Consider removing it.
Loading history...
533
				$this.siblings().superclick('hide').end().superclick('show');
534
			},
535
			out = function () {
536
				var $this = $(this),
537
					o = getOptions($this);
538
				$.proxy(close, $this, o)();
539
			},
540
			close = function (o) {
541
				o.retainPath = ($.inArray(this[0], o.$path) > -1);
542
				this.superclick('hide');
543
544
				if (!this.parents('.' + o.activeClass).length) {
545
					o.onIdle.call(getMenu(this));
546
					if (o.$path.length) {
547
						$.proxy(over, o.$path)();
548
					}
549
				}
550
			},
551
			getMenu = function ($el) {
552
				return $el.closest('.' + c.menuClass);
553
			},
554
			getOptions = function ($el) {
555
				return getMenu($el).data('sf-options');
556
			};
557
558
		return {
559
			// public methods
560
			hide: function (instant) {
561
				if (this.length) {
562
					var $this = this,
563
						o = getOptions($this);
564
					if (!o) {
565
						return this;
566
					}
567
					var not = (o.retainPath === true) ? o.$path : '',
568
						$popUp = $this.find('li.' + o.activeClass).add(this).not(not).removeClass(o.activeClass).children(o.popUpSelector),
569
						speed = o.speedOut;
570
571
					if (instant) {
572
						$popUp.show();
573
						speed = 0;
574
					}
575
					o.retainPath = false;
576
					o.onBeforeHide.call($popUp);
577
					$popUp.stop(true, true).animate(o.animationOut, speed, function () {
578
						var $this = $(this);
579
						o.onHide.call($this);
580
					});
581
				}
582
				return this;
583
			},
584
			show: function () {
585
				var o = getOptions(this);
586
				if (!o) {
587
					return this;
588
				}
589
				var $this = this.addClass(o.activeClass),
590
					$popUp = $this.children(o.popUpSelector);
591
592
				o.onBeforeShow.call($popUp);
593
				$popUp.stop(true, true).animate(o.animation, o.speed, function () {
594
					o.onShow.call($popUp);
595
				});
596
				return this;
597
			},
598
			destroy: function () {
599
				return this.each(function () {
600
					var $this = $(this),
601
						o = $this.data('sf-options'),
602
						$hasPopUp;
603
					if (!o) {
604
						return false;
605
					}
606
					$hasPopUp = $this.find(o.popUpSelector).parent('li');
607
					toggleMenuClasses($this, o);
608
					toggleAnchorClass($hasPopUp);
609
					toggleTouchAction($this);
610
					// remove event handlers
611
					$this.off('.superclick');
612
					// clear animation's inline display style
613
					$hasPopUp.children(o.popUpSelector).attr('style', function (i, style) {
614
						return style.replace(/display[^;]+;?/g, '');
615
					});
616
					// reset 'current' path classes
617
					o.$path.removeClass(o.activeClass + ' ' + c.bcClass).addClass(o.pathClass);
618
					$this.find('.' + o.activeClass).removeClass(o.activeClass);
619
					o.onDestroy.call($this);
620
					$this.removeData('sf-options');
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...
621
				});
622
			},
623
			reset: function () {
624
				return this.each(function () {
625
					var $menu = $(this),
626
						o = getOptions($menu),
627
						$openLis = $($menu.find('.' + o.activeClass).toArray().reverse());
628
					$openLis.children('a').trigger('click');
629
				});
630
			},
631
			init: function (op) {
632
				return this.each(function () {
633
					var $this = $(this);
634
					if ($this.data('sf-options')) {
635
						return false;
636
					}
637
					var o = $.extend({}, $.fn.superclick.defaults, op),
638
						$hasPopUp = $this.find(o.popUpSelector).parent('li');
639
					o.$path = setPathToCurrent($this, o);
640
641
					$this.data('sf-options', o);
642
643
					toggleMenuClasses($this, o);
644
					toggleAnchorClass($hasPopUp);
645
					toggleTouchAction($this);
646
					$this.on('click.superclick', 'a', o, clickHandler);
647
					$hasPopUp.on('dblclick.superclick', 'a', o, dblclickHandler);
648
649
					$hasPopUp.not('.' + c.bcClass).superclick('hide', true);
650
651
					o.onInit.call(this);
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...
652
				});
653
			}
654
		};
655
	})();
656
657
	$.fn.superclick = function (method, args) {
0 ignored issues
show
Unused Code introduced by
The parameter args 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...
658
		if (methods[method]) {
659
			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
660
		}
661
		else if (typeof method === 'object' || ! method) {
662
			return methods.init.apply(this, arguments);
663
		}
664
		else {
665
			return $.error('Method ' +  method + ' does not exist on jQuery.fn.superclick');
666
		}
667
	};
668
669
	$.fn.superclick.defaults = {
670
		popUpSelector: 'ul,.sf-mega', // within menu context
671
		activeClass: 'sfHover', // keep 'hover' in classname for compatibility reasons
672
		pathClass: 'overrideThisToUse',
673
		pathLevels: 1,
674
		animation: {opacity: 'show'},
675
		animationOut: {opacity: 'hide'},
676
		speed: 'normal',
677
		speedOut: 'fast',
678
		cssArrows: true,
679
		onInit: $.noop,
680
		onBeforeShow: $.noop,
681
		onShow: $.noop,
682
		onBeforeHide: $.noop,
683
		onHide: $.noop,
684
		onIdle: $.noop,
685
		onDestroy: $.noop
686
	};
687
688
})(jQuery, window);
689
690
691
/*!
692
 * @name      ElkArte news fader
693
 * @copyright ElkArte Forum contributors
694
 * @license   MIT http://www.opensource.org/licenses/mit-license.php
695
 */
696
697
/**
698
 * Inspired by Paul Mason's tutorial:
699
 * http://paulmason.name/item/simple-jquery-carousel-slider-tutorial
700
 *
701
 * Licensed under the MIT license:
702
 * http://www.opensource.org/licenses/mit-license.php
703
 */
704
;(function($) {
705
	$.fn.Elk_NewsFader = function(options) {
706
		var settings = {
707
			'iFadeDelay': 5000,
708
			'iFadeSpeed': 1000
709
		},
710
		iFadeIndex = 0,
711
		$news = $(this).find('li');
712
713
		if ($news.length > 1)
714
		{
715
			settings = $.extend(settings, options);
716
			$news.hide();
717
			$news.eq(0).fadeIn(settings.iFadeSpeed);
718
719
			setInterval(function() {
720
				$($news[iFadeIndex]).fadeOut(settings.iFadeSpeed, function() {
721
					iFadeIndex++;
722
723
					if (iFadeIndex == $news.length)
724
						iFadeIndex = 0;
0 ignored issues
show
Coding Style Best Practice introduced by
Curly braces around statements make for more readable code and help prevent bugs when you add further statements.

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

Consider:

if (a > 0)
    b = 42;

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

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

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

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

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

Loading history...
725
726
					$($news[iFadeIndex]).fadeIn(settings.iFadeSpeed);
727
				});
728
			}, settings.iFadeSpeed + settings.iFadeDelay);
729
		}
730
731
		return this;
732
	};
733
})(jQuery);
734