jquery-ui.js ➔ hue2rgb   F
last analyzed

Complexity

Conditions 57

Size

Total Lines 13
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 57
eloc 9
dl 0
loc 13
rs 0
c 0
b 0
f 0

How to fix   Complexity   

Complexity

Complex classes like jquery-ui.js ➔ hue2rgb 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
/*! jQuery UI - v1.12.0 - 2016-08-18
2
* http://jqueryui.com
3
* Includes: widget.js, data.js, disable-selection.js, scroll-parent.js, widgets/draggable.js, widgets/droppable.js, widgets/resizable.js, widgets/selectable.js, widgets/sortable.js, widgets/mouse.js, effect.js, effects/effect-blind.js, effects/effect-bounce.js, effects/effect-clip.js, effects/effect-drop.js, effects/effect-explode.js, effects/effect-fade.js, effects/effect-fold.js, effects/effect-highlight.js, effects/effect-puff.js, effects/effect-pulsate.js, effects/effect-scale.js, effects/effect-shake.js, effects/effect-size.js, effects/effect-slide.js, effects/effect-transfer.js
4
* Copyright jQuery Foundation and other contributors; Licensed MIT */
5
6
(function( factory ) {
7
	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...
8
9
		// AMD. Register as an anonymous module.
10
		define([ "jquery" ], factory );
11
	} else {
12
13
		// Browser globals
14
		factory( jQuery );
15
	}
16
}(function( $ ) {
17
18
$.ui = $.ui || {};
19
20
var version = $.ui.version = "1.12.0";
21
22
23
/*!
24
 * jQuery UI Widget 1.12.0
25
 * http://jqueryui.com
26
 *
27
 * Copyright jQuery Foundation and other contributors
28
 * Released under the MIT license.
29
 * http://jquery.org/license
30
 */
31
32
//>>label: Widget
33
//>>group: Core
34
//>>description: Provides a factory for creating stateful widgets with a common API.
35
//>>docs: http://api.jqueryui.com/jQuery.widget/
36
//>>demos: http://jqueryui.com/widget/
37
38
39
40
var widgetUuid = 0;
41
var widgetSlice = Array.prototype.slice;
42
43
$.cleanData = ( function( orig ) {
44
	return function( elems ) {
45
		var events, elem, i;
46
		for ( i = 0; ( elem = elems[ i ] ) != null; i++ ) {
0 ignored issues
show
Best Practice introduced by
Comparing elem = elems.i to null using the != operator is not safe. Consider using !== instead.
Loading history...
47
			try {
48
49
				// Only trigger remove when necessary to save time
50
				events = $._data( elem, "events" );
51
				if ( events && events.remove ) {
52
					$( elem ).triggerHandler( "remove" );
53
				}
54
55
			// Http://bugs.jquery.com/ticket/8235
56
			} 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...
57
		}
58
		orig( elems );
59
	};
60
} )( $.cleanData );
61
62
$.widget = function( name, base, prototype ) {
63
	var existingConstructor, constructor, basePrototype;
64
65
	// ProxiedPrototype allows the provided prototype to remain unmodified
66
	// so that it can be used as a mixin for multiple widgets (#8876)
67
	var proxiedPrototype = {};
68
69
	var namespace = name.split( "." )[ 0 ];
70
	name = name.split( "." )[ 1 ];
71
	var fullName = namespace + "-" + name;
72
73
	if ( !prototype ) {
74
		prototype = base;
75
		base = $.Widget;
76
	}
77
78
	if ( $.isArray( prototype ) ) {
79
		prototype = $.extend.apply( null, [ {} ].concat( prototype ) );
80
	}
81
82
	// Create selector for plugin
83
	$.expr[ ":" ][ fullName.toLowerCase() ] = function( elem ) {
84
		return !!$.data( elem, fullName );
85
	};
86
87
	$[ namespace ] = $[ namespace ] || {};
88
	existingConstructor = $[ namespace ][ name ];
89
	constructor = $[ namespace ][ name ] = function( options, element ) {
90
91
		// Allow instantiation without "new" keyword
92
		if ( !this._createWidget ) {
93
			return new constructor( options, element );
0 ignored issues
show
Coding Style Best Practice introduced by
By convention, constructors like constructor should be capitalized.
Loading history...
94
		}
95
96
		// Allow instantiation without initializing for simple inheritance
97
		// must use "new" keyword (the code above always passes args)
98
		if ( arguments.length ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if arguments.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...
99
			this._createWidget( options, 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...
100
		}
101
	};
102
103
	// Extend with the existing constructor to carry over any static properties
104
	$.extend( constructor, existingConstructor, {
105
		version: prototype.version,
106
107
		// Copy the object used to create the prototype in case we need to
108
		// redefine the widget later
109
		_proto: $.extend( {}, prototype ),
110
111
		// Track widgets that inherit from this widget in case this widget is
112
		// redefined after a widget inherits from it
113
		_childConstructors: []
114
	} );
115
116
	basePrototype = new base();
0 ignored issues
show
Coding Style Best Practice introduced by
By convention, constructors like base should be capitalized.
Loading history...
117
118
	// We need to make the options hash a property directly on the new instance
119
	// otherwise we'll modify the options hash on the prototype that we're
120
	// inheriting from
121
	basePrototype.options = $.widget.extend( {}, basePrototype.options );
122
	$.each( prototype, function( prop, value ) {
123
		if ( !$.isFunction( value ) ) {
124
			proxiedPrototype[ prop ] = value;
125
			return;
126
		}
127
		proxiedPrototype[ prop ] = ( function() {
128
			function _super() {
129
				return base.prototype[ prop ].apply( this, arguments );
130
			}
131
132
			function _superApply( args ) {
133
				return base.prototype[ prop ].apply( this, args );
134
			}
135
136
			return function() {
137
				var __super = this._super;
138
				var __superApply = this._superApply;
139
				var returnValue;
140
141
				this._super = _super;
142
				this._superApply = _superApply;
143
144
				returnValue = value.apply( this, arguments );
145
146
				this._super = __super;
147
				this._superApply = __superApply;
148
149
				return returnValue;
150
			};
151
		} )();
152
	} );
153
	constructor.prototype = $.widget.extend( basePrototype, {
154
155
		// TODO: remove support for widgetEventPrefix
156
		// always use the name + a colon as the prefix, e.g., draggable:start
157
		// don't prefix for widgets that aren't DOM-based
158
		widgetEventPrefix: existingConstructor ? ( basePrototype.widgetEventPrefix || name ) : name
159
	}, proxiedPrototype, {
160
		constructor: constructor,
161
		namespace: namespace,
162
		widgetName: name,
163
		widgetFullName: fullName
164
	} );
165
166
	// If this widget is being redefined then we need to find all widgets that
167
	// are inheriting from it and redefine all of them so that they inherit from
168
	// the new version of this widget. We're essentially trying to replace one
169
	// level in the prototype chain.
170
	if ( existingConstructor ) {
171
		$.each( existingConstructor._childConstructors, function( i, child ) {
172
			var childPrototype = child.prototype;
173
174
			// Redefine the child widget using the same prototype that was
175
			// originally used, but inherit from the new version of the base
176
			$.widget( childPrototype.namespace + "." + childPrototype.widgetName, constructor,
177
				child._proto );
178
		} );
179
180
		// Remove the list of existing child constructors from the old constructor
181
		// so the old child constructors can be garbage collected
182
		delete existingConstructor._childConstructors;
183
	} else {
184
		base._childConstructors.push( constructor );
185
	}
186
187
	$.widget.bridge( name, constructor );
188
189
	return constructor;
190
};
191
192
$.widget.extend = function( target ) {
193
	var input = widgetSlice.call( arguments, 1 );
194
	var inputIndex = 0;
195
	var inputLength = input.length;
196
	var key;
197
	var value;
198
199
	for ( ; inputIndex < inputLength; inputIndex++ ) {
200
		for ( key in input[ inputIndex ] ) {
201
			value = input[ inputIndex ][ key ];
202
			if ( input[ inputIndex ].hasOwnProperty( key ) && value !== undefined ) {
203
204
				// Clone objects
205
				if ( $.isPlainObject( value ) ) {
206
					target[ key ] = $.isPlainObject( target[ key ] ) ?
207
						$.widget.extend( {}, target[ key ], value ) :
208
209
						// Don't extend strings, arrays, etc. with objects
210
						$.widget.extend( {}, value );
211
212
				// Copy everything else by reference
213
				} else {
214
					target[ key ] = value;
215
				}
216
			}
217
		}
218
	}
219
	return target;
220
};
221
222
$.widget.bridge = function( name, object ) {
223
	var fullName = object.prototype.widgetFullName || name;
224
	$.fn[ name ] = function( options ) {
225
		var isMethodCall = typeof options === "string";
226
		var args = widgetSlice.call( arguments, 1 );
227
		var returnValue = this;
228
229
		if ( isMethodCall ) {
230
			this.each( function() {
231
				var methodValue;
232
				var instance = $.data( this, fullName );
233
234
				if ( options === "instance" ) {
235
					returnValue = instance;
236
					return false;
237
				}
238
239
				if ( !instance ) {
240
					return $.error( "cannot call methods on " + name +
241
						" prior to initialization; " +
242
						"attempted to call method '" + options + "'" );
243
				}
244
245
				if ( !$.isFunction( instance[ options ] ) || options.charAt( 0 ) === "_" ) {
246
					return $.error( "no such method '" + options + "' for " + name +
247
						" widget instance" );
248
				}
249
250
				methodValue = instance[ options ].apply( instance, args );
251
252
				if ( methodValue !== instance && methodValue !== undefined ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if methodValue !== instance...thodValue !== 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...
253
					returnValue = methodValue && methodValue.jquery ?
254
						returnValue.pushStack( methodValue.get() ) :
255
						methodValue;
256
					return false;
257
				}
258
			} );
259
		} else {
260
261
			// Allow multiple hashes to be passed on init
262
			if ( args.length ) {
263
				options = $.widget.extend.apply( null, [ options ].concat( args ) );
264
			}
265
266
			this.each( function() {
267
				var instance = $.data( this, fullName );
268
				if ( instance ) {
269
					instance.option( options || {} );
270
					if ( instance._init ) {
271
						instance._init();
272
					}
273
				} else {
274
					$.data( this, fullName, new object( options, this ) );
0 ignored issues
show
Coding Style Best Practice introduced by
By convention, constructors like object should be capitalized.
Loading history...
275
				}
276
			} );
277
		}
278
279
		return returnValue;
280
	};
281
};
282
283
$.Widget = function( /* options, element */ ) {};
284
$.Widget._childConstructors = [];
285
286
$.Widget.prototype = {
287
	widgetName: "widget",
288
	widgetEventPrefix: "",
289
	defaultElement: "<div>",
290
291
	options: {
292
		classes: {},
293
		disabled: false,
294
295
		// Callbacks
296
		create: null
297
	},
298
299
	_createWidget: function( options, element ) {
300
		element = $( element || this.defaultElement || this )[ 0 ];
301
		this.element = $( element );
302
		this.uuid = widgetUuid++;
303
		this.eventNamespace = "." + this.widgetName + this.uuid;
304
305
		this.bindings = $();
306
		this.hoverable = $();
307
		this.focusable = $();
308
		this.classesElementLookup = {};
309
310
		if ( element !== this ) {
311
			$.data( element, this.widgetFullName, this );
312
			this._on( true, this.element, {
313
				remove: function( event ) {
314
					if ( event.target === element ) {
315
						this.destroy();
316
					}
317
				}
318
			} );
319
			this.document = $( element.style ?
320
321
				// Element within the document
322
				element.ownerDocument :
323
324
				// Element is window or document
325
				element.document || element );
326
			this.window = $( this.document[ 0 ].defaultView || this.document[ 0 ].parentWindow );
327
		}
328
329
		this.options = $.widget.extend( {},
330
			this.options,
331
			this._getCreateOptions(),
332
			options );
333
334
		this._create();
335
336
		if ( this.options.disabled ) {
337
			this._setOptionDisabled( this.options.disabled );
338
		}
339
340
		this._trigger( "create", null, this._getCreateEventData() );
341
		this._init();
342
	},
343
344
	_getCreateOptions: function() {
345
		return {};
346
	},
347
348
	_getCreateEventData: $.noop,
349
350
	_create: $.noop,
351
352
	_init: $.noop,
353
354
	destroy: function() {
355
		var that = this;
356
357
		this._destroy();
358
		$.each( this.classesElementLookup, function( key, value ) {
359
			that._removeClass( value, key );
360
		} );
361
362
		// We can probably remove the unbind calls in 2.0
363
		// all event bindings should go through this._on()
364
		this.element
365
			.off( this.eventNamespace )
366
			.removeData( this.widgetFullName );
367
		this.widget()
368
			.off( this.eventNamespace )
369
			.removeAttr( "aria-disabled" );
370
371
		// Clean up events and states
372
		this.bindings.off( this.eventNamespace );
373
	},
374
375
	_destroy: $.noop,
376
377
	widget: function() {
378
		return this.element;
379
	},
380
381
	option: function( key, value ) {
382
		var options = key;
383
		var parts;
384
		var curOption;
385
		var i;
386
387
		if ( arguments.length === 0 ) {
388
389
			// Don't return a reference to the internal hash
390
			return $.widget.extend( {}, this.options );
391
		}
392
393
		if ( typeof key === "string" ) {
394
395
			// Handle nested keys, e.g., "foo.bar" => { foo: { bar: ___ } }
396
			options = {};
397
			parts = key.split( "." );
398
			key = parts.shift();
399
			if ( parts.length ) {
400
				curOption = options[ key ] = $.widget.extend( {}, this.options[ key ] );
401
				for ( i = 0; i < parts.length - 1; i++ ) {
402
					curOption[ parts[ i ] ] = curOption[ parts[ i ] ] || {};
403
					curOption = curOption[ parts[ i ] ];
404
				}
405
				key = parts.pop();
406
				if ( arguments.length === 1 ) {
407
					return curOption[ key ] === undefined ? null : curOption[ key ];
408
				}
409
				curOption[ key ] = value;
410
			} else {
411
				if ( arguments.length === 1 ) {
412
					return this.options[ key ] === undefined ? null : this.options[ key ];
413
				}
414
				options[ key ] = value;
415
			}
416
		}
417
418
		this._setOptions( options );
419
420
		return this;
421
	},
422
423
	_setOptions: function( options ) {
424
		var key;
425
426
		for ( key in options ) {
427
			this._setOption( key, options[ key ] );
428
		}
429
430
		return this;
431
	},
432
433
	_setOption: function( key, value ) {
434
		if ( key === "classes" ) {
435
			this._setOptionClasses( value );
436
		}
437
438
		this.options[ key ] = value;
439
440
		if ( key === "disabled" ) {
441
			this._setOptionDisabled( value );
442
		}
443
444
		return this;
445
	},
446
447
	_setOptionClasses: function( value ) {
448
		var classKey, elements, currentElements;
449
450
		for ( classKey in value ) {
451
			currentElements = this.classesElementLookup[ classKey ];
452
			if ( value[ classKey ] === this.options.classes[ classKey ] ||
453
					!currentElements ||
454
					!currentElements.length ) {
455
				continue;
456
			}
457
458
			// We are doing this to create a new jQuery object because the _removeClass() call
459
			// on the next line is going to destroy the reference to the current elements being
460
			// tracked. We need to save a copy of this collection so that we can add the new classes
461
			// below.
462
			elements = $( currentElements.get() );
463
			this._removeClass( currentElements, classKey );
464
465
			// We don't use _addClass() here, because that uses this.options.classes
466
			// for generating the string of classes. We want to use the value passed in from
467
			// _setOption(), this is the new value of the classes option which was passed to
468
			// _setOption(). We pass this value directly to _classes().
469
			elements.addClass( this._classes( {
470
				element: elements,
471
				keys: classKey,
472
				classes: value,
473
				add: true
474
			} ) );
475
		}
476
	},
477
478
	_setOptionDisabled: function( value ) {
479
		this._toggleClass( this.widget(), this.widgetFullName + "-disabled", null, !!value );
480
481
		// If the widget is becoming disabled, then nothing is interactive
482
		if ( value ) {
483
			this._removeClass( this.hoverable, null, "ui-state-hover" );
484
			this._removeClass( this.focusable, null, "ui-state-focus" );
485
		}
486
	},
487
488
	enable: function() {
489
		return this._setOptions( { disabled: false } );
490
	},
491
492
	disable: function() {
493
		return this._setOptions( { disabled: true } );
494
	},
495
496
	_classes: function( options ) {
497
		var full = [];
498
		var that = this;
499
500
		options = $.extend( {
501
			element: this.element,
502
			classes: this.options.classes || {}
503
		}, options );
504
505
		function processClassString( classes, checkOption ) {
506
			var current, i;
507
			for ( i = 0; i < classes.length; i++ ) {
508
				current = that.classesElementLookup[ classes[ i ] ] || $();
509
				if ( options.add ) {
510
					current = $( $.unique( current.get().concat( options.element.get() ) ) );
511
				} else {
512
					current = $( current.not( options.element ).get() );
513
				}
514
				that.classesElementLookup[ classes[ i ] ] = current;
515
				full.push( classes[ i ] );
516
				if ( checkOption && options.classes[ classes[ i ] ] ) {
517
					full.push( options.classes[ classes[ i ] ] );
518
				}
519
			}
520
		}
521
522
		if ( options.keys ) {
523
			processClassString( options.keys.match( /\S+/g ) || [], true );
524
		}
525
		if ( options.extra ) {
526
			processClassString( options.extra.match( /\S+/g ) || [] );
527
		}
528
529
		return full.join( " " );
530
	},
531
532
	_removeClass: function( element, keys, extra ) {
533
		return this._toggleClass( element, keys, extra, false );
534
	},
535
536
	_addClass: function( element, keys, extra ) {
537
		return this._toggleClass( element, keys, extra, true );
538
	},
539
540
	_toggleClass: function( element, keys, extra, add ) {
541
		add = ( typeof add === "boolean" ) ? add : extra;
542
		var shift = ( typeof element === "string" || element === null ),
543
			options = {
544
				extra: shift ? keys : extra,
545
				keys: shift ? element : keys,
546
				element: shift ? this.element : element,
547
				add: add
548
			};
549
		options.element.toggleClass( this._classes( options ), add );
550
		return this;
551
	},
552
553
	_on: function( suppressDisabledCheck, element, handlers ) {
554
		var delegateElement;
555
		var instance = this;
556
557
		// No suppressDisabledCheck flag, shuffle arguments
558
		if ( typeof suppressDisabledCheck !== "boolean" ) {
559
			handlers = element;
560
			element = suppressDisabledCheck;
561
			suppressDisabledCheck = false;
562
		}
563
564
		// No element argument, shuffle and use this.element
565
		if ( !handlers ) {
566
			handlers = element;
567
			element = this.element;
568
			delegateElement = this.widget();
569
		} else {
570
			element = delegateElement = $( element );
571
			this.bindings = this.bindings.add( element );
572
		}
573
574
		$.each( handlers, function( event, handler ) {
575
			function handlerProxy() {
576
577
				// Allow widgets to customize the disabled handling
578
				// - disabled as an array instead of boolean
579
				// - disabled class as method for disabling individual parts
580
				if ( !suppressDisabledCheck &&
581
						( instance.options.disabled === true ||
582
						$( this ).hasClass( "ui-state-disabled" ) ) ) {
583
					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...
584
				}
585
				return ( typeof handler === "string" ? instance[ handler ] : handler )
586
					.apply( instance, arguments );
587
			}
588
589
			// Copy the guid so direct unbinding works
590
			if ( typeof handler !== "string" ) {
591
				handlerProxy.guid = handler.guid =
592
					handler.guid || handlerProxy.guid || $.guid++;
593
			}
594
595
			var match = event.match( /^([\w:-]*)\s*(.*)$/ );
596
			var eventName = match[ 1 ] + instance.eventNamespace;
597
			var selector = match[ 2 ];
598
599
			if ( selector ) {
600
				delegateElement.on( eventName, selector, handlerProxy );
601
			} else {
602
				element.on( eventName, handlerProxy );
603
			}
604
		} );
605
	},
606
607
	_off: function( element, eventName ) {
608
		eventName = ( eventName || "" ).split( " " ).join( this.eventNamespace + " " ) +
609
			this.eventNamespace;
610
		element.off( eventName ).off( eventName );
611
612
		// Clear the stack to avoid memory leaks (#10056)
613
		this.bindings = $( this.bindings.not( element ).get() );
614
		this.focusable = $( this.focusable.not( element ).get() );
615
		this.hoverable = $( this.hoverable.not( element ).get() );
616
	},
617
618
	_delay: function( handler, delay ) {
619
		function handlerProxy() {
620
			return ( typeof handler === "string" ? instance[ handler ] : handler )
621
				.apply( instance, arguments );
622
		}
623
		var instance = this;
624
		return setTimeout( handlerProxy, delay || 0 );
625
	},
626
627
	_hoverable: function( element ) {
628
		this.hoverable = this.hoverable.add( element );
629
		this._on( element, {
630
			mouseenter: function( event ) {
631
				this._addClass( $( event.currentTarget ), null, "ui-state-hover" );
632
			},
633
			mouseleave: function( event ) {
634
				this._removeClass( $( event.currentTarget ), null, "ui-state-hover" );
635
			}
636
		} );
637
	},
638
639
	_focusable: function( element ) {
640
		this.focusable = this.focusable.add( element );
641
		this._on( element, {
642
			focusin: function( event ) {
643
				this._addClass( $( event.currentTarget ), null, "ui-state-focus" );
644
			},
645
			focusout: function( event ) {
646
				this._removeClass( $( event.currentTarget ), null, "ui-state-focus" );
647
			}
648
		} );
649
	},
650
651
	_trigger: function( type, event, data ) {
652
		var prop, orig;
653
		var callback = this.options[ type ];
654
655
		data = data || {};
656
		event = $.Event( event );
657
		event.type = ( type === this.widgetEventPrefix ?
658
			type :
659
			this.widgetEventPrefix + type ).toLowerCase();
660
661
		// The original event may come from any element
662
		// so we need to reset the target on the new event
663
		event.target = this.element[ 0 ];
664
665
		// Copy original event properties over to the new event
666
		orig = event.originalEvent;
667
		if ( orig ) {
668
			for ( prop in orig ) {
669
				if ( !( prop in event ) ) {
670
					event[ prop ] = orig[ prop ];
671
				}
672
			}
673
		}
674
675
		this.element.trigger( event, data );
676
		return !( $.isFunction( callback ) &&
677
			callback.apply( this.element[ 0 ], [ event ].concat( data ) ) === false ||
678
			event.isDefaultPrevented() );
679
	}
680
};
681
682
$.each( { show: "fadeIn", hide: "fadeOut" }, function( method, defaultEffect ) {
683
	$.Widget.prototype[ "_" + method ] = function( element, options, callback ) {
684
		if ( typeof options === "string" ) {
685
			options = { effect: options };
686
		}
687
688
		var hasOptions;
689
		var effectName = !options ?
690
			method :
691
			options === true || typeof options === "number" ?
692
				defaultEffect :
693
				options.effect || defaultEffect;
694
695
		options = options || {};
696
		if ( typeof options === "number" ) {
697
			options = { duration: options };
698
		}
699
700
		hasOptions = !$.isEmptyObject( options );
701
		options.complete = callback;
702
703
		if ( options.delay ) {
704
			element.delay( options.delay );
705
		}
706
707
		if ( hasOptions && $.effects && $.effects.effect[ effectName ] ) {
708
			element[ method ]( options );
709
		} else if ( effectName !== method && element[ effectName ] ) {
710
			element[ effectName ]( options.duration, options.easing, callback );
711
		} else {
712
			element.queue( function( next ) {
713
				$( this )[ method ]();
714
				if ( callback ) {
715
					callback.call( element[ 0 ] );
716
				}
717
				next();
718
			} );
719
		}
720
	};
721
} );
722
723
var widget = $.widget;
724
725
726
/*!
727
 * jQuery UI :data 1.12.0
728
 * http://jqueryui.com
729
 *
730
 * Copyright jQuery Foundation and other contributors
731
 * Released under the MIT license.
732
 * http://jquery.org/license
733
 */
734
735
//>>label: :data Selector
736
//>>group: Core
737
//>>description: Selects elements which have data stored under the specified key.
738
//>>docs: http://api.jqueryui.com/data-selector/
739
740
741
var data = $.extend( $.expr[ ":" ], {
742
	data: $.expr.createPseudo ?
743
		$.expr.createPseudo( function( dataName ) {
744
			return function( elem ) {
745
				return !!$.data( elem, dataName );
746
			};
747
		} ) :
748
749
		// Support: jQuery <1.8
750
		function( elem, i, match ) {
751
			return !!$.data( elem, match[ 3 ] );
752
		}
753
} );
754
755
/*!
756
 * jQuery UI Disable Selection 1.12.0
757
 * http://jqueryui.com
758
 *
759
 * Copyright jQuery Foundation and other contributors
760
 * Released under the MIT license.
761
 * http://jquery.org/license
762
 */
763
764
//>>label: disableSelection
765
//>>group: Core
766
//>>description: Disable selection of text content within the set of matched elements.
767
//>>docs: http://api.jqueryui.com/disableSelection/
768
769
// This file is deprecated
770
771
772
var disableSelection = $.fn.extend( {
773
	disableSelection: ( function() {
774
		var eventType = "onselectstart" in document.createElement( "div" ) ?
775
			"selectstart" :
776
			"mousedown";
777
778
		return function() {
779
			return this.on( eventType + ".ui-disableSelection", function( event ) {
780
				event.preventDefault();
781
			} );
782
		};
783
	} )(),
784
785
	enableSelection: function() {
786
		return this.off( ".ui-disableSelection" );
787
	}
788
} );
789
790
791
/*!
792
 * jQuery UI Scroll Parent 1.12.0
793
 * http://jqueryui.com
794
 *
795
 * Copyright jQuery Foundation and other contributors
796
 * Released under the MIT license.
797
 * http://jquery.org/license
798
 */
799
800
//>>label: scrollParent
801
//>>group: Core
802
//>>description: Get the closest ancestor element that is scrollable.
803
//>>docs: http://api.jqueryui.com/scrollParent/
804
805
806
807
var scrollParent = $.fn.scrollParent = function( includeHidden ) {
808
	var position = this.css( "position" ),
809
		excludeStaticParent = position === "absolute",
810
		overflowRegex = includeHidden ? /(auto|scroll|hidden)/ : /(auto|scroll)/,
811
		scrollParent = this.parents().filter( function() {
812
			var parent = $( this );
813
			if ( excludeStaticParent && parent.css( "position" ) === "static" ) {
814
				return false;
815
			}
816
			return overflowRegex.test( parent.css( "overflow" ) + parent.css( "overflow-y" ) +
817
				parent.css( "overflow-x" ) );
818
		} ).eq( 0 );
819
820
	return position === "fixed" || !scrollParent.length ?
821
		$( this[ 0 ].ownerDocument || document ) :
822
		scrollParent;
823
};
824
825
826
827
828
// This file is deprecated
829
var ie = $.ui.ie = !!/msie [\w.]+/.exec( navigator.userAgent.toLowerCase() );
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...
830
831
/*!
832
 * jQuery UI Mouse 1.12.0
833
 * http://jqueryui.com
834
 *
835
 * Copyright jQuery Foundation and other contributors
836
 * Released under the MIT license.
837
 * http://jquery.org/license
838
 */
839
840
//>>label: Mouse
841
//>>group: Widgets
842
//>>description: Abstracts mouse-based interactions to assist in creating certain widgets.
843
//>>docs: http://api.jqueryui.com/mouse/
844
845
846
847
var mouseHandled = false;
848
$( document ).on( "mouseup", function() {
849
	mouseHandled = false;
850
} );
851
852
var widgetsMouse = $.widget( "ui.mouse", {
0 ignored issues
show
Unused Code introduced by
The variable widgetsMouse seems to be never used. Consider removing it.
Loading history...
853
	version: "1.12.0",
854
	options: {
855
		cancel: "input, textarea, button, select, option",
856
		distance: 1,
857
		delay: 0
858
	},
859
	_mouseInit: function() {
860
		var that = this;
861
862
		this.element
863
			.on( "mousedown." + this.widgetName, function( event ) {
864
				return that._mouseDown( event );
865
			} )
866
			.on( "click." + this.widgetName, function( event ) {
867
				if ( true === $.data( event.target, that.widgetName + ".preventClickEvent" ) ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if true === $.data(event.ta...+ ".preventClickEvent") 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...
868
					$.removeData( event.target, that.widgetName + ".preventClickEvent" );
869
					event.stopImmediatePropagation();
870
					return false;
871
				}
872
			} );
873
874
		this.started = false;
875
	},
876
877
	// TODO: make sure destroying one instance of mouse doesn't mess with
878
	// other instances of mouse
879
	_mouseDestroy: function() {
880
		this.element.off( "." + this.widgetName );
881
		if ( this._mouseMoveDelegate ) {
882
			this.document
883
				.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
884
				.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
885
		}
886
	},
887
888
	_mouseDown: function( event ) {
889
890
		// don't let more than one widget handle mouseStart
891
		if ( mouseHandled ) {
892
			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...
893
		}
894
895
		this._mouseMoved = false;
896
897
		// We may have missed mouseup (out of window)
898
		( this._mouseStarted && this._mouseUp( event ) );
899
900
		this._mouseDownEvent = event;
901
902
		var that = this,
903
			btnIsLeft = ( event.which === 1 ),
904
905
			// event.target.nodeName works around a bug in IE 8 with
906
			// disabled inputs (#7620)
907
			elIsCancel = ( typeof this.options.cancel === "string" && event.target.nodeName ?
908
				$( event.target ).closest( this.options.cancel ).length : false );
909
		if ( !btnIsLeft || elIsCancel || !this._mouseCapture( event ) ) {
910
			return true;
911
		}
912
913
		this.mouseDelayMet = !this.options.delay;
914
		if ( !this.mouseDelayMet ) {
915
			this._mouseDelayTimer = setTimeout( function() {
916
				that.mouseDelayMet = true;
917
			}, this.options.delay );
918
		}
919
920
		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
921
			this._mouseStarted = ( this._mouseStart( event ) !== false );
922
			if ( !this._mouseStarted ) {
923
				event.preventDefault();
924
				return true;
925
			}
926
		}
927
928
		// Click event may never have fired (Gecko & Opera)
929
		if ( true === $.data( event.target, this.widgetName + ".preventClickEvent" ) ) {
930
			$.removeData( event.target, this.widgetName + ".preventClickEvent" );
931
		}
932
933
		// These delegates are required to keep context
934
		this._mouseMoveDelegate = function( event ) {
935
			return that._mouseMove( event );
936
		};
937
		this._mouseUpDelegate = function( event ) {
938
			return that._mouseUp( event );
939
		};
940
941
		this.document
942
			.on( "mousemove." + this.widgetName, this._mouseMoveDelegate )
943
			.on( "mouseup." + this.widgetName, this._mouseUpDelegate );
944
945
		event.preventDefault();
946
947
		mouseHandled = true;
948
		return true;
949
	},
950
951
	_mouseMove: function( event ) {
952
953
		// Only check for mouseups outside the document if you've moved inside the document
954
		// at least once. This prevents the firing of mouseup in the case of IE<9, which will
955
		// fire a mousemove event if content is placed under the cursor. See #7778
956
		// Support: IE <9
957
		if ( this._mouseMoved ) {
958
959
			// IE mouseup check - mouseup happened when mouse was out of window
960
			if ( $.ui.ie && ( !document.documentMode || document.documentMode < 9 ) &&
961
					!event.button ) {
962
				return this._mouseUp( event );
963
964
			// Iframe mouseup check - mouseup occurred in another document
965
			} else if ( !event.which ) {
966
967
				// Support: Safari <=8 - 9
968
				// Safari sets which to 0 if you press any of the following keys
969
				// during a drag (#14461)
970
				if ( event.originalEvent.altKey || event.originalEvent.ctrlKey ||
971
						event.originalEvent.metaKey || event.originalEvent.shiftKey ) {
972
					this.ignoreMissingWhich = true;
973
				} else if ( !this.ignoreMissingWhich ) {
974
					return this._mouseUp( event );
975
				}
976
			}
977
		}
978
979
		if ( event.which || event.button ) {
980
			this._mouseMoved = true;
981
		}
982
983
		if ( this._mouseStarted ) {
984
			this._mouseDrag( event );
985
			return event.preventDefault();
986
		}
987
988
		if ( this._mouseDistanceMet( event ) && this._mouseDelayMet( event ) ) {
989
			this._mouseStarted =
990
				( this._mouseStart( this._mouseDownEvent, event ) !== false );
991
			( this._mouseStarted ? this._mouseDrag( event ) : this._mouseUp( event ) );
992
		}
993
994
		return !this._mouseStarted;
995
	},
996
997
	_mouseUp: function( event ) {
998
		this.document
999
			.off( "mousemove." + this.widgetName, this._mouseMoveDelegate )
1000
			.off( "mouseup." + this.widgetName, this._mouseUpDelegate );
1001
1002
		if ( this._mouseStarted ) {
1003
			this._mouseStarted = false;
1004
1005
			if ( event.target === this._mouseDownEvent.target ) {
1006
				$.data( event.target, this.widgetName + ".preventClickEvent", true );
1007
			}
1008
1009
			this._mouseStop( event );
1010
		}
1011
1012
		if ( this._mouseDelayTimer ) {
1013
			clearTimeout( this._mouseDelayTimer );
1014
			delete this._mouseDelayTimer;
1015
		}
1016
1017
		this.ignoreMissingWhich = false;
1018
		mouseHandled = false;
1019
		event.preventDefault();
1020
	},
1021
1022
	_mouseDistanceMet: function( event ) {
1023
		return ( Math.max(
1024
				Math.abs( this._mouseDownEvent.pageX - event.pageX ),
1025
				Math.abs( this._mouseDownEvent.pageY - event.pageY )
1026
			) >= this.options.distance
1027
		);
1028
	},
1029
1030
	_mouseDelayMet: function( /* event */ ) {
1031
		return this.mouseDelayMet;
1032
	},
1033
1034
	// These are placeholder methods, to be overriden by extending plugin
1035
	_mouseStart: function( /* event */ ) {},
1036
	_mouseDrag: function( /* event */ ) {},
1037
	_mouseStop: function( /* event */ ) {},
1038
	_mouseCapture: function( /* event */ ) { return true; }
1039
} );
1040
1041
1042
1043
1044
// $.ui.plugin is deprecated. Use $.widget() extensions instead.
1045
var plugin = $.ui.plugin = {
1046
	add: function( module, option, set ) {
1047
		var i,
1048
			proto = $.ui[ module ].prototype;
1049
		for ( i in set ) {
1050
			proto.plugins[ i ] = proto.plugins[ i ] || [];
1051
			proto.plugins[ i ].push( [ option, set[ i ] ] );
1052
		}
1053
	},
1054
	call: function( instance, name, args, allowDisconnected ) {
1055
		var i,
1056
			set = instance.plugins[ name ];
1057
1058
		if ( !set ) {
1059
			return;
1060
		}
1061
1062
		if ( !allowDisconnected && ( !instance.element[ 0 ].parentNode ||
1063
				instance.element[ 0 ].parentNode.nodeType === 11 ) ) {
1064
			return;
1065
		}
1066
1067
		for ( i = 0; i < set.length; i++ ) {
1068
			if ( instance.options[ set[ i ][ 0 ] ] ) {
1069
				set[ i ][ 1 ].apply( instance.element, args );
1070
			}
1071
		}
1072
	}
1073
};
1074
1075
1076
1077
var safeActiveElement = $.ui.safeActiveElement = function( document ) {
1078
	var activeElement;
1079
1080
	// Support: IE 9 only
1081
	// IE9 throws an "Unspecified error" accessing document.activeElement from an <iframe>
1082
	try {
1083
		activeElement = document.activeElement;
1084
	} catch ( error ) {
1085
		activeElement = document.body;
1086
	}
1087
1088
	// Support: IE 9 - 11 only
1089
	// IE may return null instead of an element
1090
	// Interestingly, this only seems to occur when NOT in an iframe
1091
	if ( !activeElement ) {
1092
		activeElement = document.body;
1093
	}
1094
1095
	// Support: IE 11 only
1096
	// IE11 returns a seemingly empty object in some cases when accessing
1097
	// document.activeElement from an <iframe>
1098
	if ( !activeElement.nodeName ) {
1099
		activeElement = document.body;
1100
	}
1101
1102
	return activeElement;
1103
};
1104
1105
1106
1107
var safeBlur = $.ui.safeBlur = function( element ) {
1108
1109
	// Support: IE9 - 10 only
1110
	// If the <body> is blurred, IE will switch windows, see #9420
1111
	if ( element && element.nodeName.toLowerCase() !== "body" ) {
1112
		$( element ).trigger( "blur" );
1113
	}
1114
};
1115
1116
1117
/*!
1118
 * jQuery UI Draggable 1.12.0
1119
 * http://jqueryui.com
1120
 *
1121
 * Copyright jQuery Foundation and other contributors
1122
 * Released under the MIT license.
1123
 * http://jquery.org/license
1124
 */
1125
1126
//>>label: Draggable
1127
//>>group: Interactions
1128
//>>description: Enables dragging functionality for any element.
1129
//>>docs: http://api.jqueryui.com/draggable/
1130
//>>demos: http://jqueryui.com/draggable/
1131
//>>css.structure: ../../themes/base/draggable.css
1132
1133
1134
1135
$.widget( "ui.draggable", $.ui.mouse, {
1136
	version: "1.12.0",
1137
	widgetEventPrefix: "drag",
1138
	options: {
1139
		addClasses: true,
1140
		appendTo: "parent",
1141
		axis: false,
1142
		connectToSortable: false,
1143
		containment: false,
1144
		cursor: "auto",
1145
		cursorAt: false,
1146
		grid: false,
1147
		handle: false,
1148
		helper: "original",
1149
		iframeFix: false,
1150
		opacity: false,
1151
		refreshPositions: false,
1152
		revert: false,
1153
		revertDuration: 500,
1154
		scope: "default",
1155
		scroll: true,
1156
		scrollSensitivity: 20,
1157
		scrollSpeed: 20,
1158
		snap: false,
1159
		snapMode: "both",
1160
		snapTolerance: 20,
1161
		stack: false,
1162
		zIndex: false,
1163
1164
		// Callbacks
1165
		drag: null,
1166
		start: null,
1167
		stop: null
1168
	},
1169
	_create: function() {
1170
1171
		if ( this.options.helper === "original" ) {
1172
			this._setPositionRelative();
1173
		}
1174
		if ( this.options.addClasses ) {
1175
			this._addClass( "ui-draggable" );
1176
		}
1177
		this._setHandleClassName();
1178
1179
		this._mouseInit();
1180
	},
1181
1182
	_setOption: function( key, value ) {
1183
		this._super( key, value );
1184
		if ( key === "handle" ) {
1185
			this._removeHandleClassName();
1186
			this._setHandleClassName();
1187
		}
1188
	},
1189
1190
	_destroy: function() {
1191
		if ( ( this.helper || this.element ).is( ".ui-draggable-dragging" ) ) {
1192
			this.destroyOnClear = true;
1193
			return;
1194
		}
1195
		this._removeHandleClassName();
1196
		this._mouseDestroy();
1197
	},
1198
1199
	_mouseCapture: function( event ) {
1200
		var o = this.options;
1201
1202
		this._blurActiveElement( event );
1203
1204
		// Among others, prevent a drag on a resizable-handle
1205
		if ( this.helper || o.disabled ||
1206
				$( event.target ).closest( ".ui-resizable-handle" ).length > 0 ) {
1207
			return false;
1208
		}
1209
1210
		//Quit if we're not on a valid handle
1211
		this.handle = this._getHandle( event );
1212
		if ( !this.handle ) {
1213
			return false;
1214
		}
1215
1216
		this._blockFrames( o.iframeFix === true ? "iframe" : o.iframeFix );
1217
1218
		return true;
1219
1220
	},
1221
1222
	_blockFrames: function( selector ) {
1223
		this.iframeBlocks = this.document.find( selector ).map( function() {
1224
			var iframe = $( this );
1225
1226
			return $( "<div>" )
1227
				.css( "position", "absolute" )
1228
				.appendTo( iframe.parent() )
1229
				.outerWidth( iframe.outerWidth() )
1230
				.outerHeight( iframe.outerHeight() )
1231
				.offset( iframe.offset() )[ 0 ];
1232
		} );
1233
	},
1234
1235
	_unblockFrames: function() {
1236
		if ( this.iframeBlocks ) {
1237
			this.iframeBlocks.remove();
1238
			delete this.iframeBlocks;
1239
		}
1240
	},
1241
1242
	_blurActiveElement: function( event ) {
1243
		var activeElement = $.ui.safeActiveElement( this.document[ 0 ] ),
1244
			target = $( event.target );
1245
1246
		// Only blur if the event occurred on an element that is:
1247
		// 1) within the draggable handle
1248
		// 2) but not within the currently focused element
1249
		// See #10527, #12472
1250
		if ( this._getHandle( event ) && target.closest( activeElement ).length ) {
1251
			return;
1252
		}
1253
1254
		// Blur any element that currently has focus, see #4261
1255
		$.ui.safeBlur( activeElement );
1256
	},
1257
1258
	_mouseStart: function( event ) {
1259
1260
		var o = this.options;
1261
1262
		//Create and append the visible helper
1263
		this.helper = this._createHelper( event );
1264
1265
		this._addClass( this.helper, "ui-draggable-dragging" );
1266
1267
		//Cache the helper size
1268
		this._cacheHelperProportions();
1269
1270
		//If ddmanager is used for droppables, set the global draggable
1271
		if ( $.ui.ddmanager ) {
1272
			$.ui.ddmanager.current = this;
1273
		}
1274
1275
		/*
1276
		 * - Position generation -
1277
		 * This block generates everything position related - it's the core of draggables.
1278
		 */
1279
1280
		//Cache the margins of the original element
1281
		this._cacheMargins();
1282
1283
		//Store the helper's css position
1284
		this.cssPosition = this.helper.css( "position" );
1285
		this.scrollParent = this.helper.scrollParent( true );
1286
		this.offsetParent = this.helper.offsetParent();
1287
		this.hasFixedAncestor = this.helper.parents().filter( function() {
1288
				return $( this ).css( "position" ) === "fixed";
1289
			} ).length > 0;
1290
1291
		//The element's absolute position on the page minus margins
1292
		this.positionAbs = this.element.offset();
1293
		this._refreshOffsets( event );
1294
1295
		//Generate the original position
1296
		this.originalPosition = this.position = this._generatePosition( event, false );
1297
		this.originalPageX = event.pageX;
1298
		this.originalPageY = event.pageY;
1299
1300
		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
1301
		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
1302
1303
		//Set a containment if given in the options
1304
		this._setContainment();
1305
1306
		//Trigger event + callbacks
1307
		if ( this._trigger( "start", event ) === false ) {
1308
			this._clear();
1309
			return false;
1310
		}
1311
1312
		//Recache the helper size
1313
		this._cacheHelperProportions();
1314
1315
		//Prepare the droppable offsets
1316
		if ( $.ui.ddmanager && !o.dropBehaviour ) {
1317
			$.ui.ddmanager.prepareOffsets( this, event );
1318
		}
1319
1320
		// Execute the drag once - this causes the helper not to be visible before getting its
1321
		// correct position
1322
		this._mouseDrag( event, true );
1323
1324
		// If the ddmanager is used for droppables, inform the manager that dragging has started
1325
		// (see #5003)
1326
		if ( $.ui.ddmanager ) {
1327
			$.ui.ddmanager.dragStart( this, event );
1328
		}
1329
1330
		return true;
1331
	},
1332
1333
	_refreshOffsets: function( event ) {
1334
		this.offset = {
1335
			top: this.positionAbs.top - this.margins.top,
1336
			left: this.positionAbs.left - this.margins.left,
1337
			scroll: false,
1338
			parent: this._getParentOffset(),
1339
			relative: this._getRelativeOffset()
1340
		};
1341
1342
		this.offset.click = {
1343
			left: event.pageX - this.offset.left,
1344
			top: event.pageY - this.offset.top
1345
		};
1346
	},
1347
1348
	_mouseDrag: function( event, noPropagation ) {
1349
1350
		// reset any necessary cached properties (see #5009)
1351
		if ( this.hasFixedAncestor ) {
1352
			this.offset.parent = this._getParentOffset();
1353
		}
1354
1355
		//Compute the helpers position
1356
		this.position = this._generatePosition( event, true );
1357
		this.positionAbs = this._convertPositionTo( "absolute" );
1358
1359
		//Call plugins and callbacks and use the resulting position if something is returned
1360
		if ( !noPropagation ) {
1361
			var ui = this._uiHash();
1362
			if ( this._trigger( "drag", event, ui ) === false ) {
1363
				this._mouseUp( new $.Event( "mouseup", event ) );
1364
				return false;
1365
			}
1366
			this.position = ui.position;
1367
		}
1368
1369
		this.helper[ 0 ].style.left = this.position.left + "px";
1370
		this.helper[ 0 ].style.top = this.position.top + "px";
1371
1372
		if ( $.ui.ddmanager ) {
1373
			$.ui.ddmanager.drag( this, event );
1374
		}
1375
1376
		return false;
1377
	},
1378
1379
	_mouseStop: function( event ) {
1380
1381
		//If we are using droppables, inform the manager about the drop
1382
		var that = this,
1383
			dropped = false;
1384
		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
1385
			dropped = $.ui.ddmanager.drop( this, event );
1386
		}
1387
1388
		//if a drop comes from outside (a sortable)
1389
		if ( this.dropped ) {
1390
			dropped = this.dropped;
1391
			this.dropped = false;
1392
		}
1393
1394
		if ( ( this.options.revert === "invalid" && !dropped ) ||
1395
				( this.options.revert === "valid" && dropped ) ||
1396
				this.options.revert === true || ( $.isFunction( this.options.revert ) &&
1397
				this.options.revert.call( this.element, dropped ) )
1398
		) {
1399
			$( this.helper ).animate(
1400
				this.originalPosition,
1401
				parseInt( this.options.revertDuration, 10 ),
1402
				function() {
1403
					if ( that._trigger( "stop", event ) !== false ) {
1404
						that._clear();
1405
					}
1406
				}
1407
			);
1408
		} else {
1409
			if ( this._trigger( "stop", event ) !== false ) {
1410
				this._clear();
1411
			}
1412
		}
1413
1414
		return false;
1415
	},
1416
1417
	_mouseUp: function( event ) {
1418
		this._unblockFrames();
1419
1420
		// If the ddmanager is used for droppables, inform the manager that dragging has stopped
1421
		// (see #5003)
1422
		if ( $.ui.ddmanager ) {
1423
			$.ui.ddmanager.dragStop( this, event );
1424
		}
1425
1426
		// Only need to focus if the event occurred on the draggable itself, see #10527
1427
		if ( this.handleElement.is( event.target ) ) {
1428
1429
			// The interaction is over; whether or not the click resulted in a drag,
1430
			// focus the element
1431
			this.element.trigger( "focus" );
1432
		}
1433
1434
		return $.ui.mouse.prototype._mouseUp.call( this, event );
1435
	},
1436
1437
	cancel: function() {
1438
1439
		if ( this.helper.is( ".ui-draggable-dragging" ) ) {
1440
			this._mouseUp( new $.Event( "mouseup", { target: this.element[ 0 ] } ) );
1441
		} else {
1442
			this._clear();
1443
		}
1444
1445
		return this;
1446
1447
	},
1448
1449
	_getHandle: function( event ) {
1450
		return this.options.handle ?
1451
			!!$( event.target ).closest( this.element.find( this.options.handle ) ).length :
1452
			true;
1453
	},
1454
1455
	_setHandleClassName: function() {
1456
		this.handleElement = this.options.handle ?
1457
			this.element.find( this.options.handle ) : this.element;
1458
		this._addClass( this.handleElement, "ui-draggable-handle" );
1459
	},
1460
1461
	_removeHandleClassName: function() {
1462
		this._removeClass( this.handleElement, "ui-draggable-handle" );
1463
	},
1464
1465
	_createHelper: function( event ) {
1466
1467
		var o = this.options,
1468
			helperIsFunction = $.isFunction( o.helper ),
1469
			helper = helperIsFunction ?
1470
				$( o.helper.apply( this.element[ 0 ], [ event ] ) ) :
1471
				( o.helper === "clone" ?
1472
					this.element.clone().removeAttr( "id" ) :
1473
					this.element );
1474
1475
		if ( !helper.parents( "body" ).length ) {
1476
			helper.appendTo( ( o.appendTo === "parent" ?
1477
				this.element[ 0 ].parentNode :
1478
				o.appendTo ) );
1479
		}
1480
1481
		// Http://bugs.jqueryui.com/ticket/9446
1482
		// a helper function can return the original element
1483
		// which wouldn't have been set to relative in _create
1484
		if ( helperIsFunction && helper[ 0 ] === this.element[ 0 ] ) {
1485
			this._setPositionRelative();
1486
		}
1487
1488
		if ( helper[ 0 ] !== this.element[ 0 ] &&
1489
				!( /(fixed|absolute)/ ).test( helper.css( "position" ) ) ) {
1490
			helper.css( "position", "absolute" );
1491
		}
1492
1493
		return helper;
1494
1495
	},
1496
1497
	_setPositionRelative: function() {
1498
		if ( !( /^(?:r|a|f)/ ).test( this.element.css( "position" ) ) ) {
1499
			this.element[ 0 ].style.position = "relative";
1500
		}
1501
	},
1502
1503 View Code Duplication
	_adjustOffsetFromHelper: function( obj ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1504
		if ( typeof obj === "string" ) {
1505
			obj = obj.split( " " );
1506
		}
1507
		if ( $.isArray( obj ) ) {
1508
			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
1509
		}
1510
		if ( "left" in obj ) {
1511
			this.offset.click.left = obj.left + this.margins.left;
1512
		}
1513
		if ( "right" in obj ) {
1514
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
1515
		}
1516
		if ( "top" in obj ) {
1517
			this.offset.click.top = obj.top + this.margins.top;
1518
		}
1519
		if ( "bottom" in obj ) {
1520
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
1521
		}
1522
	},
1523
1524
	_isRootNode: function( element ) {
1525
		return ( /(html|body)/i ).test( element.tagName ) || element === this.document[ 0 ];
1526
	},
1527
1528
	_getParentOffset: function() {
1529
1530
		//Get the offsetParent and cache its position
1531
		var po = this.offsetParent.offset(),
1532
			document = this.document[ 0 ];
1533
1534
		// This is a special case where we need to modify a offset calculated on start, since the
1535
		// following happened:
1536
		// 1. The position of the helper is absolute, so it's position is calculated based on the
1537
		// next positioned parent
1538
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
1539
		// the document, which means that the scroll is included in the initial calculation of the
1540
		// offset of the parent, and never recalculated upon drag
1541
		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== document &&
1542
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
1543
			po.left += this.scrollParent.scrollLeft();
1544
			po.top += this.scrollParent.scrollTop();
1545
		}
1546
1547
		if ( this._isRootNode( this.offsetParent[ 0 ] ) ) {
1548
			po = { top: 0, left: 0 };
1549
		}
1550
1551
		return {
1552
			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
1553
			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
1554
		};
1555
1556
	},
1557
1558
	_getRelativeOffset: function() {
1559
		if ( this.cssPosition !== "relative" ) {
1560
			return { top: 0, left: 0 };
1561
		}
1562
1563
		var p = this.element.position(),
1564
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1565
1566
		return {
1567
			top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
1568
				( !scrollIsRootNode ? this.scrollParent.scrollTop() : 0 ),
1569
			left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
1570
				( !scrollIsRootNode ? this.scrollParent.scrollLeft() : 0 )
1571
		};
1572
1573
	},
1574
1575
	_cacheMargins: function() {
1576
		this.margins = {
1577
			left: ( parseInt( this.element.css( "marginLeft" ), 10 ) || 0 ),
1578
			top: ( parseInt( this.element.css( "marginTop" ), 10 ) || 0 ),
1579
			right: ( parseInt( this.element.css( "marginRight" ), 10 ) || 0 ),
1580
			bottom: ( parseInt( this.element.css( "marginBottom" ), 10 ) || 0 )
1581
		};
1582
	},
1583
1584
	_cacheHelperProportions: function() {
1585
		this.helperProportions = {
1586
			width: this.helper.outerWidth(),
1587
			height: this.helper.outerHeight()
1588
		};
1589
	},
1590
1591
	_setContainment: function() {
1592
1593
		var isUserScrollable, c, ce,
1594
			o = this.options,
1595
			document = this.document[ 0 ];
1596
1597
		this.relativeContainer = null;
1598
1599
		if ( !o.containment ) {
1600
			this.containment = null;
1601
			return;
1602
		}
1603
1604
		if ( o.containment === "window" ) {
1605
			this.containment = [
1606
				$( window ).scrollLeft() - this.offset.relative.left - this.offset.parent.left,
1607
				$( window ).scrollTop() - this.offset.relative.top - this.offset.parent.top,
1608
				$( window ).scrollLeft() + $( window ).width() -
1609
					this.helperProportions.width - this.margins.left,
1610
				$( window ).scrollTop() +
1611
					( $( window ).height() || document.body.parentNode.scrollHeight ) -
1612
					this.helperProportions.height - this.margins.top
1613
			];
1614
			return;
1615
		}
1616
1617
		if ( o.containment === "document" ) {
1618
			this.containment = [
1619
				0,
1620
				0,
1621
				$( document ).width() - this.helperProportions.width - this.margins.left,
1622
				( $( document ).height() || document.body.parentNode.scrollHeight ) -
1623
					this.helperProportions.height - this.margins.top
1624
			];
1625
			return;
1626
		}
1627
1628
		if ( o.containment.constructor === Array ) {
1629
			this.containment = o.containment;
1630
			return;
1631
		}
1632
1633
		if ( o.containment === "parent" ) {
1634
			o.containment = this.helper[ 0 ].parentNode;
1635
		}
1636
1637
		c = $( o.containment );
1638
		ce = c[ 0 ];
1639
1640
		if ( !ce ) {
1641
			return;
1642
		}
1643
1644
		isUserScrollable = /(scroll|auto)/.test( c.css( "overflow" ) );
1645
1646
		this.containment = [
1647
			( parseInt( c.css( "borderLeftWidth" ), 10 ) || 0 ) +
1648
				( parseInt( c.css( "paddingLeft" ), 10 ) || 0 ),
1649
			( parseInt( c.css( "borderTopWidth" ), 10 ) || 0 ) +
1650
				( parseInt( c.css( "paddingTop" ), 10 ) || 0 ),
1651
			( isUserScrollable ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
1652
				( parseInt( c.css( "borderRightWidth" ), 10 ) || 0 ) -
1653
				( parseInt( c.css( "paddingRight" ), 10 ) || 0 ) -
1654
				this.helperProportions.width -
1655
				this.margins.left -
1656
				this.margins.right,
1657
			( isUserScrollable ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
1658
				( parseInt( c.css( "borderBottomWidth" ), 10 ) || 0 ) -
1659
				( parseInt( c.css( "paddingBottom" ), 10 ) || 0 ) -
1660
				this.helperProportions.height -
1661
				this.margins.top -
1662
				this.margins.bottom
1663
		];
1664
		this.relativeContainer = c;
1665
	},
1666
1667
	_convertPositionTo: function( d, pos ) {
1668
1669
		if ( !pos ) {
1670
			pos = this.position;
1671
		}
1672
1673
		var mod = d === "absolute" ? 1 : -1,
1674
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] );
1675
1676
		return {
1677
			top: (
1678
1679
				// The absolute mouse position
1680
				pos.top	+
1681
1682
				// Only for relative positioned nodes: Relative offset from element to offset parent
1683
				this.offset.relative.top * mod +
1684
1685
				// The offsetParent's offset without borders (offset + border)
1686
				this.offset.parent.top * mod -
1687
				( ( this.cssPosition === "fixed" ?
1688
					-this.offset.scroll.top :
1689
					( scrollIsRootNode ? 0 : this.offset.scroll.top ) ) * mod )
1690
			),
1691
			left: (
1692
1693
				// The absolute mouse position
1694
				pos.left +
1695
1696
				// Only for relative positioned nodes: Relative offset from element to offset parent
1697
				this.offset.relative.left * mod +
1698
1699
				// The offsetParent's offset without borders (offset + border)
1700
				this.offset.parent.left * mod	-
1701
				( ( this.cssPosition === "fixed" ?
1702
					-this.offset.scroll.left :
1703
					( scrollIsRootNode ? 0 : this.offset.scroll.left ) ) * mod )
1704
			)
1705
		};
1706
1707
	},
1708
1709
	_generatePosition: function( event, constrainPosition ) {
1710
1711
		var containment, co, top, left,
1712
			o = this.options,
1713
			scrollIsRootNode = this._isRootNode( this.scrollParent[ 0 ] ),
1714
			pageX = event.pageX,
1715
			pageY = event.pageY;
1716
1717
		// Cache the scroll
1718
		if ( !scrollIsRootNode || !this.offset.scroll ) {
1719
			this.offset.scroll = {
1720
				top: this.scrollParent.scrollTop(),
1721
				left: this.scrollParent.scrollLeft()
1722
			};
1723
		}
1724
1725
		/*
1726
		 * - Position constraining -
1727
		 * Constrain the position to a mix of grid, containment.
1728
		 */
1729
1730
		// If we are not dragging yet, we won't check for options
1731
		if ( constrainPosition ) {
1732
			if ( this.containment ) {
1733
				if ( this.relativeContainer ) {
1734
					co = this.relativeContainer.offset();
1735
					containment = [
1736
						this.containment[ 0 ] + co.left,
1737
						this.containment[ 1 ] + co.top,
1738
						this.containment[ 2 ] + co.left,
1739
						this.containment[ 3 ] + co.top
1740
					];
1741
				} else {
1742
					containment = this.containment;
1743
				}
1744
1745
				if ( event.pageX - this.offset.click.left < containment[ 0 ] ) {
1746
					pageX = containment[ 0 ] + this.offset.click.left;
1747
				}
1748
				if ( event.pageY - this.offset.click.top < containment[ 1 ] ) {
1749
					pageY = containment[ 1 ] + this.offset.click.top;
1750
				}
1751
				if ( event.pageX - this.offset.click.left > containment[ 2 ] ) {
1752
					pageX = containment[ 2 ] + this.offset.click.left;
1753
				}
1754
				if ( event.pageY - this.offset.click.top > containment[ 3 ] ) {
1755
					pageY = containment[ 3 ] + this.offset.click.top;
1756
				}
1757
			}
1758
1759 View Code Duplication
			if ( o.grid ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
1760
1761
				//Check for grid elements set to 0 to prevent divide by 0 error causing invalid
1762
				// argument errors in IE (see ticket #6950)
1763
				top = o.grid[ 1 ] ? this.originalPageY + Math.round( ( pageY -
1764
					this.originalPageY ) / o.grid[ 1 ] ) * o.grid[ 1 ] : this.originalPageY;
1765
				pageY = containment ? ( ( top - this.offset.click.top >= containment[ 1 ] ||
1766
					top - this.offset.click.top > containment[ 3 ] ) ?
1767
						top :
1768
						( ( top - this.offset.click.top >= containment[ 1 ] ) ?
1769
							top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) : top;
1770
1771
				left = o.grid[ 0 ] ? this.originalPageX +
1772
					Math.round( ( pageX - this.originalPageX ) / o.grid[ 0 ] ) * o.grid[ 0 ] :
1773
					this.originalPageX;
1774
				pageX = containment ? ( ( left - this.offset.click.left >= containment[ 0 ] ||
1775
					left - this.offset.click.left > containment[ 2 ] ) ?
1776
						left :
1777
						( ( left - this.offset.click.left >= containment[ 0 ] ) ?
1778
							left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) : left;
1779
			}
1780
1781
			if ( o.axis === "y" ) {
1782
				pageX = this.originalPageX;
1783
			}
1784
1785
			if ( o.axis === "x" ) {
1786
				pageY = this.originalPageY;
1787
			}
1788
		}
1789
1790
		return {
1791
			top: (
1792
1793
				// The absolute mouse position
1794
				pageY -
1795
1796
				// Click offset (relative to the element)
1797
				this.offset.click.top -
1798
1799
				// Only for relative positioned nodes: Relative offset from element to offset parent
1800
				this.offset.relative.top -
1801
1802
				// The offsetParent's offset without borders (offset + border)
1803
				this.offset.parent.top +
1804
				( this.cssPosition === "fixed" ?
1805
					-this.offset.scroll.top :
1806
					( scrollIsRootNode ? 0 : this.offset.scroll.top ) )
1807
			),
1808
			left: (
1809
1810
				// The absolute mouse position
1811
				pageX -
1812
1813
				// Click offset (relative to the element)
1814
				this.offset.click.left -
1815
1816
				// Only for relative positioned nodes: Relative offset from element to offset parent
1817
				this.offset.relative.left -
1818
1819
				// The offsetParent's offset without borders (offset + border)
1820
				this.offset.parent.left +
1821
				( this.cssPosition === "fixed" ?
1822
					-this.offset.scroll.left :
1823
					( scrollIsRootNode ? 0 : this.offset.scroll.left ) )
1824
			)
1825
		};
1826
1827
	},
1828
1829
	_clear: function() {
1830
		this._removeClass( this.helper, "ui-draggable-dragging" );
1831
		if ( this.helper[ 0 ] !== this.element[ 0 ] && !this.cancelHelperRemoval ) {
1832
			this.helper.remove();
1833
		}
1834
		this.helper = null;
1835
		this.cancelHelperRemoval = false;
1836
		if ( this.destroyOnClear ) {
1837
			this.destroy();
1838
		}
1839
	},
1840
1841
	// From now on bulk stuff - mainly helpers
1842
1843
	_trigger: function( type, event, ui ) {
1844
		ui = ui || this._uiHash();
1845
		$.ui.plugin.call( this, type, [ event, ui, this ], true );
1846
1847
		// Absolute position and offset (see #6884 ) have to be recalculated after plugins
1848
		if ( /^(drag|start|stop)/.test( type ) ) {
1849
			this.positionAbs = this._convertPositionTo( "absolute" );
1850
			ui.offset = this.positionAbs;
1851
		}
1852
		return $.Widget.prototype._trigger.call( this, type, event, ui );
1853
	},
1854
1855
	plugins: {},
1856
1857
	_uiHash: function() {
1858
		return {
1859
			helper: this.helper,
1860
			position: this.position,
1861
			originalPosition: this.originalPosition,
1862
			offset: this.positionAbs
1863
		};
1864
	}
1865
1866
} );
1867
1868
$.ui.plugin.add( "draggable", "connectToSortable", {
1869
	start: function( event, ui, draggable ) {
1870
		var uiSortable = $.extend( {}, ui, {
1871
			item: draggable.element
1872
		} );
1873
1874
		draggable.sortables = [];
1875
		$( draggable.options.connectToSortable ).each( function() {
1876
			var sortable = $( this ).sortable( "instance" );
1877
1878
			if ( sortable && !sortable.options.disabled ) {
1879
				draggable.sortables.push( sortable );
1880
1881
				// RefreshPositions is called at drag start to refresh the containerCache
1882
				// which is used in drag. This ensures it's initialized and synchronized
1883
				// with any changes that might have happened on the page since initialization.
1884
				sortable.refreshPositions();
1885
				sortable._trigger( "activate", event, uiSortable );
1886
			}
1887
		} );
1888
	},
1889
	stop: function( event, ui, draggable ) {
1890
		var uiSortable = $.extend( {}, ui, {
1891
			item: draggable.element
1892
		} );
1893
1894
		draggable.cancelHelperRemoval = false;
1895
1896
		$.each( draggable.sortables, function() {
1897
			var sortable = this;
1898
1899
			if ( sortable.isOver ) {
1900
				sortable.isOver = 0;
1901
1902
				// Allow this sortable to handle removing the helper
1903
				draggable.cancelHelperRemoval = true;
1904
				sortable.cancelHelperRemoval = false;
1905
1906
				// Use _storedCSS To restore properties in the sortable,
1907
				// as this also handles revert (#9675) since the draggable
1908
				// may have modified them in unexpected ways (#8809)
1909
				sortable._storedCSS = {
1910
					position: sortable.placeholder.css( "position" ),
1911
					top: sortable.placeholder.css( "top" ),
1912
					left: sortable.placeholder.css( "left" )
1913
				};
1914
1915
				sortable._mouseStop( event );
1916
1917
				// Once drag has ended, the sortable should return to using
1918
				// its original helper, not the shared helper from draggable
1919
				sortable.options.helper = sortable.options._helper;
1920
			} else {
1921
1922
				// Prevent this Sortable from removing the helper.
1923
				// However, don't set the draggable to remove the helper
1924
				// either as another connected Sortable may yet handle the removal.
1925
				sortable.cancelHelperRemoval = true;
1926
1927
				sortable._trigger( "deactivate", event, uiSortable );
1928
			}
1929
		} );
1930
	},
1931
	drag: function( event, ui, draggable ) {
1932
		$.each( draggable.sortables, function() {
1933
			var innermostIntersecting = false,
1934
				sortable = this;
1935
1936
			// Copy over variables that sortable's _intersectsWith uses
1937
			sortable.positionAbs = draggable.positionAbs;
1938
			sortable.helperProportions = draggable.helperProportions;
1939
			sortable.offset.click = draggable.offset.click;
1940
1941
			if ( sortable._intersectsWith( sortable.containerCache ) ) {
1942
				innermostIntersecting = true;
1943
1944
				$.each( draggable.sortables, function() {
1945
1946
					// Copy over variables that sortable's _intersectsWith uses
1947
					this.positionAbs = draggable.positionAbs;
1948
					this.helperProportions = draggable.helperProportions;
1949
					this.offset.click = draggable.offset.click;
1950
1951
					if ( this !== sortable &&
1952
							this._intersectsWith( this.containerCache ) &&
1953
							$.contains( sortable.element[ 0 ], this.element[ 0 ] ) ) {
1954
						innermostIntersecting = false;
1955
					}
1956
1957
					return innermostIntersecting;
1958
				} );
1959
			}
1960
1961
			if ( innermostIntersecting ) {
1962
1963
				// If it intersects, we use a little isOver variable and set it once,
1964
				// so that the move-in stuff gets fired only once.
1965
				if ( !sortable.isOver ) {
1966
					sortable.isOver = 1;
1967
1968
					// Store draggable's parent in case we need to reappend to it later.
1969
					draggable._parent = ui.helper.parent();
1970
1971
					sortable.currentItem = ui.helper
1972
						.appendTo( sortable.element )
1973
						.data( "ui-sortable-item", true );
1974
1975
					// Store helper option to later restore it
1976
					sortable.options._helper = sortable.options.helper;
1977
1978
					sortable.options.helper = function() {
1979
						return ui.helper[ 0 ];
1980
					};
1981
1982
					// Fire the start events of the sortable with our passed browser event,
1983
					// and our own helper (so it doesn't create a new one)
1984
					event.target = sortable.currentItem[ 0 ];
1985
					sortable._mouseCapture( event, true );
1986
					sortable._mouseStart( event, true, true );
1987
1988
					// Because the browser event is way off the new appended portlet,
1989
					// modify necessary variables to reflect the changes
1990
					sortable.offset.click.top = draggable.offset.click.top;
1991
					sortable.offset.click.left = draggable.offset.click.left;
1992
					sortable.offset.parent.left -= draggable.offset.parent.left -
1993
						sortable.offset.parent.left;
1994
					sortable.offset.parent.top -= draggable.offset.parent.top -
1995
						sortable.offset.parent.top;
1996
1997
					draggable._trigger( "toSortable", event );
1998
1999
					// Inform draggable that the helper is in a valid drop zone,
2000
					// used solely in the revert option to handle "valid/invalid".
2001
					draggable.dropped = sortable.element;
2002
2003
					// Need to refreshPositions of all sortables in the case that
2004
					// adding to one sortable changes the location of the other sortables (#9675)
2005
					$.each( draggable.sortables, function() {
2006
						this.refreshPositions();
2007
					} );
2008
2009
					// Hack so receive/update callbacks work (mostly)
2010
					draggable.currentItem = draggable.element;
2011
					sortable.fromOutside = draggable;
2012
				}
2013
2014
				if ( sortable.currentItem ) {
2015
					sortable._mouseDrag( event );
2016
2017
					// Copy the sortable's position because the draggable's can potentially reflect
2018
					// a relative position, while sortable is always absolute, which the dragged
2019
					// element has now become. (#8809)
2020
					ui.position = sortable.position;
2021
				}
2022
			} else {
2023
2024
				// If it doesn't intersect with the sortable, and it intersected before,
2025
				// we fake the drag stop of the sortable, but make sure it doesn't remove
2026
				// the helper by using cancelHelperRemoval.
2027
				if ( sortable.isOver ) {
2028
2029
					sortable.isOver = 0;
2030
					sortable.cancelHelperRemoval = true;
2031
2032
					// Calling sortable's mouseStop would trigger a revert,
2033
					// so revert must be temporarily false until after mouseStop is called.
2034
					sortable.options._revert = sortable.options.revert;
2035
					sortable.options.revert = false;
2036
2037
					sortable._trigger( "out", event, sortable._uiHash( sortable ) );
2038
					sortable._mouseStop( event, true );
2039
2040
					// Restore sortable behaviors that were modfied
2041
					// when the draggable entered the sortable area (#9481)
2042
					sortable.options.revert = sortable.options._revert;
2043
					sortable.options.helper = sortable.options._helper;
2044
2045
					if ( sortable.placeholder ) {
2046
						sortable.placeholder.remove();
2047
					}
2048
2049
					// Restore and recalculate the draggable's offset considering the sortable
2050
					// may have modified them in unexpected ways. (#8809, #10669)
2051
					ui.helper.appendTo( draggable._parent );
2052
					draggable._refreshOffsets( event );
2053
					ui.position = draggable._generatePosition( event, true );
2054
2055
					draggable._trigger( "fromSortable", event );
2056
2057
					// Inform draggable that the helper is no longer in a valid drop zone
2058
					draggable.dropped = false;
2059
2060
					// Need to refreshPositions of all sortables just in case removing
2061
					// from one sortable changes the location of other sortables (#9675)
2062
					$.each( draggable.sortables, function() {
2063
						this.refreshPositions();
2064
					} );
2065
				}
2066
			}
2067
		} );
2068
	}
2069
} );
2070
2071
$.ui.plugin.add( "draggable", "cursor", {
2072
	start: function( event, ui, instance ) {
2073
		var t = $( "body" ),
2074
			o = instance.options;
2075
2076
		if ( t.css( "cursor" ) ) {
2077
			o._cursor = t.css( "cursor" );
2078
		}
2079
		t.css( "cursor", o.cursor );
2080
	},
2081
	stop: function( event, ui, instance ) {
2082
		var o = instance.options;
2083
		if ( o._cursor ) {
2084
			$( "body" ).css( "cursor", o._cursor );
2085
		}
2086
	}
2087
} );
2088
2089
$.ui.plugin.add( "draggable", "opacity", {
2090
	start: function( event, ui, instance ) {
2091
		var t = $( ui.helper ),
2092
			o = instance.options;
2093
		if ( t.css( "opacity" ) ) {
2094
			o._opacity = t.css( "opacity" );
2095
		}
2096
		t.css( "opacity", o.opacity );
2097
	},
2098
	stop: function( event, ui, instance ) {
2099
		var o = instance.options;
2100
		if ( o._opacity ) {
2101
			$( ui.helper ).css( "opacity", o._opacity );
2102
		}
2103
	}
2104
} );
2105
2106
$.ui.plugin.add( "draggable", "scroll", {
2107
	start: function( event, ui, i ) {
2108
		if ( !i.scrollParentNotHidden ) {
2109
			i.scrollParentNotHidden = i.helper.scrollParent( false );
2110
		}
2111
2112
		if ( i.scrollParentNotHidden[ 0 ] !== i.document[ 0 ] &&
2113
				i.scrollParentNotHidden[ 0 ].tagName !== "HTML" ) {
2114
			i.overflowOffset = i.scrollParentNotHidden.offset();
2115
		}
2116
	},
2117
	drag: function( event, ui, i  ) {
2118
2119
		var o = i.options,
2120
			scrolled = false,
2121
			scrollParent = i.scrollParentNotHidden[ 0 ],
2122
			document = i.document[ 0 ];
2123
2124
		if ( scrollParent !== document && scrollParent.tagName !== "HTML" ) {
2125
			if ( !o.axis || o.axis !== "x" ) {
2126
				if ( ( i.overflowOffset.top + scrollParent.offsetHeight ) - event.pageY <
2127
						o.scrollSensitivity ) {
2128
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop + o.scrollSpeed;
2129
				} else if ( event.pageY - i.overflowOffset.top < o.scrollSensitivity ) {
2130
					scrollParent.scrollTop = scrolled = scrollParent.scrollTop - o.scrollSpeed;
2131
				}
2132
			}
2133
2134
			if ( !o.axis || o.axis !== "y" ) {
2135
				if ( ( i.overflowOffset.left + scrollParent.offsetWidth ) - event.pageX <
2136
						o.scrollSensitivity ) {
2137
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft + o.scrollSpeed;
2138
				} else if ( event.pageX - i.overflowOffset.left < o.scrollSensitivity ) {
2139
					scrollParent.scrollLeft = scrolled = scrollParent.scrollLeft - o.scrollSpeed;
2140
				}
2141
			}
2142
2143
		} else {
2144
2145
			if ( !o.axis || o.axis !== "x" ) {
2146
				if ( event.pageY - $( document ).scrollTop() < o.scrollSensitivity ) {
2147
					scrolled = $( document ).scrollTop( $( document ).scrollTop() - o.scrollSpeed );
2148
				} else if ( $( window ).height() - ( event.pageY - $( document ).scrollTop() ) <
2149
						o.scrollSensitivity ) {
2150
					scrolled = $( document ).scrollTop( $( document ).scrollTop() + o.scrollSpeed );
2151
				}
2152
			}
2153
2154
			if ( !o.axis || o.axis !== "y" ) {
2155
				if ( event.pageX - $( document ).scrollLeft() < o.scrollSensitivity ) {
2156
					scrolled = $( document ).scrollLeft(
2157
						$( document ).scrollLeft() - o.scrollSpeed
2158
					);
2159
				} else if ( $( window ).width() - ( event.pageX - $( document ).scrollLeft() ) <
2160
						o.scrollSensitivity ) {
2161
					scrolled = $( document ).scrollLeft(
2162
						$( document ).scrollLeft() + o.scrollSpeed
2163
					);
2164
				}
2165
			}
2166
2167
		}
2168
2169
		if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
2170
			$.ui.ddmanager.prepareOffsets( i, event );
2171
		}
2172
2173
	}
2174
} );
2175
2176
$.ui.plugin.add( "draggable", "snap", {
2177
	start: function( event, ui, i ) {
2178
2179
		var o = i.options;
2180
2181
		i.snapElements = [];
2182
2183
		$( o.snap.constructor !== String ? ( o.snap.items || ":data(ui-draggable)" ) : o.snap )
2184
			.each( function() {
2185
				var $t = $( this ),
2186
					$o = $t.offset();
2187
				if ( this !== i.element[ 0 ] ) {
2188
					i.snapElements.push( {
2189
						item: this,
2190
						width: $t.outerWidth(), height: $t.outerHeight(),
2191
						top: $o.top, left: $o.left
2192
					} );
2193
				}
2194
			} );
2195
2196
	},
2197
	drag: function( event, ui, inst ) {
2198
2199
		var ts, bs, ls, rs, l, r, t, b, i, first,
2200
			o = inst.options,
2201
			d = o.snapTolerance,
2202
			x1 = ui.offset.left, x2 = x1 + inst.helperProportions.width,
2203
			y1 = ui.offset.top, y2 = y1 + inst.helperProportions.height;
2204
2205
		for ( i = inst.snapElements.length - 1; i >= 0; i-- ) {
2206
2207
			l = inst.snapElements[ i ].left - inst.margins.left;
2208
			r = l + inst.snapElements[ i ].width;
2209
			t = inst.snapElements[ i ].top - inst.margins.top;
2210
			b = t + inst.snapElements[ i ].height;
2211
2212
			if ( x2 < l - d || x1 > r + d || y2 < t - d || y1 > b + d ||
2213
					!$.contains( inst.snapElements[ i ].item.ownerDocument,
2214
					inst.snapElements[ i ].item ) ) {
2215
				if ( inst.snapElements[ i ].snapping ) {
2216
					( inst.options.snap.release &&
2217
						inst.options.snap.release.call(
2218
							inst.element,
2219
							event,
2220
							$.extend( inst._uiHash(), { snapItem: inst.snapElements[ i ].item } )
2221
						) );
2222
				}
2223
				inst.snapElements[ i ].snapping = false;
2224
				continue;
2225
			}
2226
2227 View Code Duplication
			if ( o.snapMode !== "inner" ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2228
				ts = Math.abs( t - y2 ) <= d;
2229
				bs = Math.abs( b - y1 ) <= d;
2230
				ls = Math.abs( l - x2 ) <= d;
2231
				rs = Math.abs( r - x1 ) <= d;
2232
				if ( ts ) {
2233
					ui.position.top = inst._convertPositionTo( "relative", {
2234
						top: t - inst.helperProportions.height,
2235
						left: 0
2236
					} ).top;
2237
				}
2238
				if ( bs ) {
2239
					ui.position.top = inst._convertPositionTo( "relative", {
2240
						top: b,
2241
						left: 0
2242
					} ).top;
2243
				}
2244
				if ( ls ) {
2245
					ui.position.left = inst._convertPositionTo( "relative", {
2246
						top: 0,
2247
						left: l - inst.helperProportions.width
2248
					} ).left;
2249
				}
2250
				if ( rs ) {
2251
					ui.position.left = inst._convertPositionTo( "relative", {
2252
						top: 0,
2253
						left: r
2254
					} ).left;
2255
				}
2256
			}
2257
2258
			first = ( ts || bs || ls || rs );
2259
2260 View Code Duplication
			if ( o.snapMode !== "outer" ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
2261
				ts = Math.abs( t - y1 ) <= d;
2262
				bs = Math.abs( b - y2 ) <= d;
2263
				ls = Math.abs( l - x1 ) <= d;
2264
				rs = Math.abs( r - x2 ) <= d;
2265
				if ( ts ) {
2266
					ui.position.top = inst._convertPositionTo( "relative", {
2267
						top: t,
2268
						left: 0
2269
					} ).top;
2270
				}
2271
				if ( bs ) {
2272
					ui.position.top = inst._convertPositionTo( "relative", {
2273
						top: b - inst.helperProportions.height,
2274
						left: 0
2275
					} ).top;
2276
				}
2277
				if ( ls ) {
2278
					ui.position.left = inst._convertPositionTo( "relative", {
2279
						top: 0,
2280
						left: l
2281
					} ).left;
2282
				}
2283
				if ( rs ) {
2284
					ui.position.left = inst._convertPositionTo( "relative", {
2285
						top: 0,
2286
						left: r - inst.helperProportions.width
2287
					} ).left;
2288
				}
2289
			}
2290
2291
			if ( !inst.snapElements[ i ].snapping && ( ts || bs || ls || rs || first ) ) {
2292
				( inst.options.snap.snap &&
2293
					inst.options.snap.snap.call(
2294
						inst.element,
2295
						event,
2296
						$.extend( inst._uiHash(), {
2297
							snapItem: inst.snapElements[ i ].item
2298
						} ) ) );
2299
			}
2300
			inst.snapElements[ i ].snapping = ( ts || bs || ls || rs || first );
2301
2302
		}
2303
2304
	}
2305
} );
2306
2307
$.ui.plugin.add( "draggable", "stack", {
2308
	start: function( event, ui, instance ) {
2309
		var min,
2310
			o = instance.options,
2311
			group = $.makeArray( $( o.stack ) ).sort( function( a, b ) {
2312
				return ( parseInt( $( a ).css( "zIndex" ), 10 ) || 0 ) -
2313
					( parseInt( $( b ).css( "zIndex" ), 10 ) || 0 );
2314
			} );
2315
2316
		if ( !group.length ) { return; }
2317
2318
		min = parseInt( $( group[ 0 ] ).css( "zIndex" ), 10 ) || 0;
2319
		$( group ).each( function( i ) {
2320
			$( this ).css( "zIndex", min + i );
2321
		} );
2322
		this.css( "zIndex", ( min + group.length ) );
2323
	}
2324
} );
2325
2326
$.ui.plugin.add( "draggable", "zIndex", {
2327
	start: function( event, ui, instance ) {
2328
		var t = $( ui.helper ),
2329
			o = instance.options;
2330
2331
		if ( t.css( "zIndex" ) ) {
2332
			o._zIndex = t.css( "zIndex" );
2333
		}
2334
		t.css( "zIndex", o.zIndex );
2335
	},
2336
	stop: function( event, ui, instance ) {
2337
		var o = instance.options;
2338
2339
		if ( o._zIndex ) {
2340
			$( ui.helper ).css( "zIndex", o._zIndex );
2341
		}
2342
	}
2343
} );
2344
2345
var widgetsDraggable = $.ui.draggable;
0 ignored issues
show
Unused Code introduced by
The variable widgetsDraggable seems to be never used. Consider removing it.
Loading history...
2346
2347
2348
/*!
2349
 * jQuery UI Droppable 1.12.0
2350
 * http://jqueryui.com
2351
 *
2352
 * Copyright jQuery Foundation and other contributors
2353
 * Released under the MIT license.
2354
 * http://jquery.org/license
2355
 */
2356
2357
//>>label: Droppable
2358
//>>group: Interactions
2359
//>>description: Enables drop targets for draggable elements.
2360
//>>docs: http://api.jqueryui.com/droppable/
2361
//>>demos: http://jqueryui.com/droppable/
2362
2363
2364
2365
$.widget( "ui.droppable", {
2366
	version: "1.12.0",
2367
	widgetEventPrefix: "drop",
2368
	options: {
2369
		accept: "*",
2370
		addClasses: true,
2371
		greedy: false,
2372
		scope: "default",
2373
		tolerance: "intersect",
2374
2375
		// Callbacks
2376
		activate: null,
2377
		deactivate: null,
2378
		drop: null,
2379
		out: null,
2380
		over: null
2381
	},
2382
	_create: function() {
2383
2384
		var proportions,
2385
			o = this.options,
2386
			accept = o.accept;
2387
2388
		this.isover = false;
2389
		this.isout = true;
2390
2391
		this.accept = $.isFunction( accept ) ? accept : function( d ) {
2392
			return d.is( accept );
2393
		};
2394
2395
		this.proportions = function( /* valueToWrite */ ) {
2396
			if ( arguments.length ) {
2397
2398
				// Store the droppable's proportions
2399
				proportions = arguments[ 0 ];
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...
2400
			} else {
2401
2402
				// Retrieve or derive the droppable's proportions
2403
				return proportions ?
2404
					proportions :
2405
					proportions = {
2406
						width: this.element[ 0 ].offsetWidth,
2407
						height: this.element[ 0 ].offsetHeight
2408
					};
2409
			}
2410
		};
2411
2412
		this._addToManager( o.scope );
2413
2414
		o.addClasses && this._addClass( "ui-droppable" );
2415
2416
	},
2417
2418
	_addToManager: function( scope ) {
2419
2420
		// Add the reference and positions to the manager
2421
		$.ui.ddmanager.droppables[ scope ] = $.ui.ddmanager.droppables[ scope ] || [];
2422
		$.ui.ddmanager.droppables[ scope ].push( this );
2423
	},
2424
2425
	_splice: function( drop ) {
2426
		var i = 0;
2427
		for ( ; i < drop.length; i++ ) {
2428
			if ( drop[ i ] === this ) {
2429
				drop.splice( i, 1 );
2430
			}
2431
		}
2432
	},
2433
2434
	_destroy: function() {
2435
		var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2436
2437
		this._splice( drop );
2438
	},
2439
2440
	_setOption: function( key, value ) {
2441
2442
		if ( key === "accept" ) {
2443
			this.accept = $.isFunction( value ) ? value : function( d ) {
2444
				return d.is( value );
2445
			};
2446
		} else if ( key === "scope" ) {
2447
			var drop = $.ui.ddmanager.droppables[ this.options.scope ];
2448
2449
			this._splice( drop );
2450
			this._addToManager( value );
2451
		}
2452
2453
		this._super( key, value );
2454
	},
2455
2456
	_activate: function( event ) {
2457
		var draggable = $.ui.ddmanager.current;
2458
2459
		this._addActiveClass();
2460
		if ( draggable ) {
2461
			this._trigger( "activate", event, this.ui( draggable ) );
2462
		}
2463
	},
2464
2465
	_deactivate: function( event ) {
2466
		var draggable = $.ui.ddmanager.current;
2467
2468
		this._removeActiveClass();
2469
		if ( draggable ) {
2470
			this._trigger( "deactivate", event, this.ui( draggable ) );
2471
		}
2472
	},
2473
2474
	_over: function( event ) {
2475
2476
		var draggable = $.ui.ddmanager.current;
2477
2478
		// Bail if draggable and droppable are same element
2479
		if ( !draggable || ( draggable.currentItem ||
2480
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
2481
			return;
2482
		}
2483
2484
		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
2485
				draggable.element ) ) ) {
2486
			this._addHoverClass();
2487
			this._trigger( "over", event, this.ui( draggable ) );
2488
		}
2489
2490
	},
2491
2492
	_out: function( event ) {
2493
2494
		var draggable = $.ui.ddmanager.current;
2495
2496
		// Bail if draggable and droppable are same element
2497
		if ( !draggable || ( draggable.currentItem ||
2498
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
2499
			return;
2500
		}
2501
2502
		if ( this.accept.call( this.element[ 0 ], ( draggable.currentItem ||
2503
				draggable.element ) ) ) {
2504
			this._removeHoverClass();
2505
			this._trigger( "out", event, this.ui( draggable ) );
2506
		}
2507
2508
	},
2509
2510
	_drop: function( event, custom ) {
2511
2512
		var draggable = custom || $.ui.ddmanager.current,
2513
			childrenIntersection = false;
2514
2515
		// Bail if draggable and droppable are same element
2516
		if ( !draggable || ( draggable.currentItem ||
2517
				draggable.element )[ 0 ] === this.element[ 0 ] ) {
2518
			return false;
2519
		}
2520
2521
		this.element
2522
			.find( ":data(ui-droppable)" )
2523
			.not( ".ui-draggable-dragging" )
2524
			.each( function() {
2525
				var inst = $( this ).droppable( "instance" );
2526
				if (
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if inst.options.greedy && !...tions.tolerance, event) 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...
2527
					inst.options.greedy &&
2528
					!inst.options.disabled &&
2529
					inst.options.scope === draggable.options.scope &&
2530
					inst.accept.call(
2531
						inst.element[ 0 ], ( draggable.currentItem || draggable.element )
2532
					) &&
2533
					intersect(
2534
						draggable,
2535
						$.extend( inst, { offset: inst.element.offset() } ),
2536
						inst.options.tolerance, event
2537
					)
2538
				) {
2539
					childrenIntersection = true;
2540
					return false; }
2541
			} );
2542
		if ( childrenIntersection ) {
2543
			return false;
2544
		}
2545
2546
		if ( this.accept.call( this.element[ 0 ],
2547
				( draggable.currentItem || draggable.element ) ) ) {
2548
			this._removeActiveClass();
2549
			this._removeHoverClass();
2550
2551
			this._trigger( "drop", event, this.ui( draggable ) );
2552
			return this.element;
2553
		}
2554
2555
		return false;
2556
2557
	},
2558
2559
	ui: function( c ) {
2560
		return {
2561
			draggable: ( c.currentItem || c.element ),
2562
			helper: c.helper,
2563
			position: c.position,
2564
			offset: c.positionAbs
2565
		};
2566
	},
2567
2568
	// Extension points just to make backcompat sane and avoid duplicating logic
2569
	// TODO: Remove in 1.13 along with call to it below
2570
	_addHoverClass: function() {
2571
		this._addClass( "ui-droppable-hover" );
2572
	},
2573
2574
	_removeHoverClass: function() {
2575
		this._removeClass( "ui-droppable-hover" );
2576
	},
2577
2578
	_addActiveClass: function() {
2579
		this._addClass( "ui-droppable-active" );
2580
	},
2581
2582
	_removeActiveClass: function() {
2583
		this._removeClass( "ui-droppable-active" );
2584
	}
2585
} );
2586
2587
var intersect = $.ui.intersect = ( function() {
2588
	function isOverAxis( x, reference, size ) {
2589
		return ( x >= reference ) && ( x < ( reference + size ) );
2590
	}
2591
2592
	return function( draggable, droppable, toleranceMode, event ) {
2593
2594
		if ( !droppable.offset ) {
2595
			return false;
2596
		}
2597
2598
		var x1 = ( draggable.positionAbs ||
2599
				draggable.position.absolute ).left + draggable.margins.left,
2600
			y1 = ( draggable.positionAbs ||
2601
				draggable.position.absolute ).top + draggable.margins.top,
2602
			x2 = x1 + draggable.helperProportions.width,
2603
			y2 = y1 + draggable.helperProportions.height,
2604
			l = droppable.offset.left,
2605
			t = droppable.offset.top,
2606
			r = l + droppable.proportions().width,
2607
			b = t + droppable.proportions().height;
2608
2609
		switch ( toleranceMode ) {
2610
		case "fit":
2611
			return ( l <= x1 && x2 <= r && t <= y1 && y2 <= b );
2612
		case "intersect":
2613
			return ( l < x1 + ( draggable.helperProportions.width / 2 ) && // Right Half
2614
				x2 - ( draggable.helperProportions.width / 2 ) < r && // Left Half
2615
				t < y1 + ( draggable.helperProportions.height / 2 ) && // Bottom Half
2616
				y2 - ( draggable.helperProportions.height / 2 ) < b ); // Top Half
2617
		case "pointer":
2618
			return isOverAxis( event.pageY, t, droppable.proportions().height ) &&
2619
				isOverAxis( event.pageX, l, droppable.proportions().width );
2620
		case "touch":
2621
			return (
2622
				( y1 >= t && y1 <= b ) || // Top edge touching
2623
				( y2 >= t && y2 <= b ) || // Bottom edge touching
2624
				( y1 < t && y2 > b ) // Surrounded vertically
2625
			) && (
2626
				( x1 >= l && x1 <= r ) || // Left edge touching
2627
				( x2 >= l && x2 <= r ) || // Right edge touching
2628
				( x1 < l && x2 > r ) // Surrounded horizontally
2629
			);
2630
		default:
2631
			return false;
2632
		}
2633
	};
2634
} )();
2635
2636
/*
2637
	This manager tracks offsets of draggables and droppables
2638
*/
2639
$.ui.ddmanager = {
2640
	current: null,
2641
	droppables: { "default": [] },
2642
	prepareOffsets: function( t, event ) {
2643
2644
		var i, j,
2645
			m = $.ui.ddmanager.droppables[ t.options.scope ] || [],
2646
			type = event ? event.type : null, // workaround for #2317
2647
			list = ( t.currentItem || t.element ).find( ":data(ui-droppable)" ).addBack();
2648
2649
		droppablesLoop: for ( i = 0; i < m.length; i++ ) {
2650
2651
			// No disabled and non-accepted
2652
			if ( m[ i ].options.disabled || ( t && !m[ i ].accept.call( m[ i ].element[ 0 ],
2653
					( t.currentItem || t.element ) ) ) ) {
2654
				continue;
2655
			}
2656
2657
			// Filter out elements in the current dragged item
2658
			for ( j = 0; j < list.length; j++ ) {
2659
				if ( list[ j ] === m[ i ].element[ 0 ] ) {
2660
					m[ i ].proportions().height = 0;
2661
					continue droppablesLoop;
2662
				}
2663
			}
2664
2665
			m[ i ].visible = m[ i ].element.css( "display" ) !== "none";
2666
			if ( !m[ i ].visible ) {
2667
				continue;
2668
			}
2669
2670
			// Activate the droppable if used directly from draggables
2671
			if ( type === "mousedown" ) {
2672
				m[ i ]._activate.call( m[ i ], event );
2673
			}
2674
2675
			m[ i ].offset = m[ i ].element.offset();
2676
			m[ i ].proportions( {
2677
				width: m[ i ].element[ 0 ].offsetWidth,
2678
				height: m[ i ].element[ 0 ].offsetHeight
2679
			} );
2680
2681
		}
2682
2683
	},
2684
	drop: function( draggable, event ) {
2685
2686
		var dropped = false;
2687
2688
		// Create a copy of the droppables in case the list changes during the drop (#9116)
2689
		$.each( ( $.ui.ddmanager.droppables[ draggable.options.scope ] || [] ).slice(), function() {
2690
2691
			if ( !this.options ) {
2692
				return;
2693
			}
2694
			if ( !this.options.disabled && this.visible &&
2695
					intersect( draggable, this, this.options.tolerance, event ) ) {
2696
				dropped = this._drop.call( this, event ) || dropped;
2697
			}
2698
2699
			if ( !this.options.disabled && this.visible && this.accept.call( this.element[ 0 ],
2700
					( draggable.currentItem || draggable.element ) ) ) {
2701
				this.isout = true;
2702
				this.isover = false;
2703
				this._deactivate.call( this, event );
2704
			}
2705
2706
		} );
2707
		return dropped;
2708
2709
	},
2710
	dragStart: function( draggable, event ) {
2711
2712
		// Listen for scrolling so that if the dragging causes scrolling the position of the
2713
		// droppables can be recalculated (see #5003)
2714
		draggable.element.parentsUntil( "body" ).on( "scroll.droppable", function() {
2715
			if ( !draggable.options.refreshPositions ) {
2716
				$.ui.ddmanager.prepareOffsets( draggable, event );
2717
			}
2718
		} );
2719
	},
2720
	drag: function( draggable, event ) {
2721
2722
		// If you have a highly dynamic page, you might try this option. It renders positions
2723
		// every time you move the mouse.
2724
		if ( draggable.options.refreshPositions ) {
2725
			$.ui.ddmanager.prepareOffsets( draggable, event );
2726
		}
2727
2728
		// Run through all droppables and check their positions based on specific tolerance options
2729
		$.each( $.ui.ddmanager.droppables[ draggable.options.scope ] || [], function() {
2730
2731
			if ( this.options.disabled || this.greedyChild || !this.visible ) {
2732
				return;
2733
			}
2734
2735
			var parentInstance, scope, parent,
2736
				intersects = intersect( draggable, this, this.options.tolerance, event ),
2737
				c = !intersects && this.isover ?
2738
					"isout" :
2739
					( intersects && !this.isover ? "isover" : null );
2740
			if ( !c ) {
2741
				return;
2742
			}
2743
2744
			if ( this.options.greedy ) {
2745
2746
				// find droppable parents with same scope
2747
				scope = this.options.scope;
2748
				parent = this.element.parents( ":data(ui-droppable)" ).filter( function() {
2749
					return $( this ).droppable( "instance" ).options.scope === scope;
2750
				} );
2751
2752
				if ( parent.length ) {
2753
					parentInstance = $( parent[ 0 ] ).droppable( "instance" );
2754
					parentInstance.greedyChild = ( c === "isover" );
2755
				}
2756
			}
2757
2758
			// We just moved into a greedy child
2759
			if ( parentInstance && c === "isover" ) {
2760
				parentInstance.isover = false;
2761
				parentInstance.isout = true;
2762
				parentInstance._out.call( parentInstance, event );
2763
			}
2764
2765
			this[ c ] = true;
2766
			this[ c === "isout" ? "isover" : "isout" ] = false;
2767
			this[ c === "isover" ? "_over" : "_out" ].call( this, event );
2768
2769
			// We just moved out of a greedy child
2770
			if ( parentInstance && c === "isout" ) {
2771
				parentInstance.isout = false;
2772
				parentInstance.isover = true;
2773
				parentInstance._over.call( parentInstance, event );
2774
			}
2775
		} );
2776
2777
	},
2778
	dragStop: function( draggable, event ) {
2779
		draggable.element.parentsUntil( "body" ).off( "scroll.droppable" );
2780
2781
		// Call prepareOffsets one final time since IE does not fire return scroll events when
2782
		// overflow was caused by drag (see #5003)
2783
		if ( !draggable.options.refreshPositions ) {
2784
			$.ui.ddmanager.prepareOffsets( draggable, event );
2785
		}
2786
	}
2787
};
2788
2789
// DEPRECATED
2790
// TODO: switch return back to widget declaration at top of file when this is removed
2791
if ( $.uiBackCompat !== false ) {
2792
2793
	// Backcompat for activeClass and hoverClass options
2794
	$.widget( "ui.droppable", $.ui.droppable, {
2795
		options: {
2796
			hoverClass: false,
2797
			activeClass: false
2798
		},
2799
		_addActiveClass: function() {
2800
			this._super();
2801
			if ( this.options.activeClass ) {
2802
				this.element.addClass( this.options.activeClass );
2803
			}
2804
		},
2805
		_removeActiveClass: function() {
2806
			this._super();
2807
			if ( this.options.activeClass ) {
2808
				this.element.removeClass( this.options.activeClass );
2809
			}
2810
		},
2811
		_addHoverClass: function() {
2812
			this._super();
2813
			if ( this.options.hoverClass ) {
2814
				this.element.addClass( this.options.hoverClass );
2815
			}
2816
		},
2817
		_removeHoverClass: function() {
2818
			this._super();
2819
			if ( this.options.hoverClass ) {
2820
				this.element.removeClass( this.options.hoverClass );
2821
			}
2822
		}
2823
	} );
2824
}
2825
2826
var widgetsDroppable = $.ui.droppable;
0 ignored issues
show
Unused Code introduced by
The variable widgetsDroppable seems to be never used. Consider removing it.
Loading history...
2827
2828
2829
/*!
2830
 * jQuery UI Resizable 1.12.0
2831
 * http://jqueryui.com
2832
 *
2833
 * Copyright jQuery Foundation and other contributors
2834
 * Released under the MIT license.
2835
 * http://jquery.org/license
2836
 */
2837
2838
//>>label: Resizable
2839
//>>group: Interactions
2840
//>>description: Enables resize functionality for any element.
2841
//>>docs: http://api.jqueryui.com/resizable/
2842
//>>demos: http://jqueryui.com/resizable/
2843
//>>css.structure: ../../themes/base/core.css
2844
//>>css.structure: ../../themes/base/resizable.css
2845
//>>css.theme: ../../themes/base/theme.css
2846
2847
2848
2849
$.widget( "ui.resizable", $.ui.mouse, {
2850
	version: "1.12.0",
2851
	widgetEventPrefix: "resize",
2852
	options: {
2853
		alsoResize: false,
2854
		animate: false,
2855
		animateDuration: "slow",
2856
		animateEasing: "swing",
2857
		aspectRatio: false,
2858
		autoHide: false,
2859
		classes: {
2860
			"ui-resizable-se": "ui-icon ui-icon-gripsmall-diagonal-se"
2861
		},
2862
		containment: false,
2863
		ghost: false,
2864
		grid: false,
2865
		handles: "e,s,se",
2866
		helper: false,
2867
		maxHeight: null,
2868
		maxWidth: null,
2869
		minHeight: 10,
2870
		minWidth: 10,
2871
2872
		// See #7960
2873
		zIndex: 90,
2874
2875
		// Callbacks
2876
		resize: null,
2877
		start: null,
2878
		stop: null
2879
	},
2880
2881
	_num: function( value ) {
2882
		return parseFloat( value ) || 0;
2883
	},
2884
2885
	_isNumber: function( value ) {
2886
		return !isNaN( parseFloat( value ) );
2887
	},
2888
2889
	_hasScroll: function( el, a ) {
2890
2891
		if ( $( el ).css( "overflow" ) === "hidden" ) {
2892
			return false;
2893
		}
2894
2895
		var scroll = ( a && a === "left" ) ? "scrollLeft" : "scrollTop",
2896
			has = false;
0 ignored issues
show
Unused Code introduced by
The assignment to variable has seems to be never used. Consider removing it.
Loading history...
2897
2898
		if ( el[ scroll ] > 0 ) {
2899
			return true;
2900
		}
2901
2902
		// TODO: determine which cases actually cause this to happen
2903
		// if the element doesn't have the scroll set, see if it's possible to
2904
		// set the scroll
2905
		el[ scroll ] = 1;
2906
		has = ( el[ scroll ] > 0 );
2907
		el[ scroll ] = 0;
2908
		return has;
2909
	},
2910
2911
	_create: function() {
2912
2913
		var margins,
2914
			o = this.options,
2915
			that = this;
2916
		this._addClass( "ui-resizable" );
2917
2918
		$.extend( this, {
2919
			_aspectRatio: !!( o.aspectRatio ),
2920
			aspectRatio: o.aspectRatio,
2921
			originalElement: this.element,
2922
			_proportionallyResizeElements: [],
2923
			_helper: o.helper || o.ghost || o.animate ? o.helper || "ui-resizable-helper" : null
2924
		} );
2925
2926
		// Wrap the element if it cannot hold child nodes
2927
		if ( this.element[ 0 ].nodeName.match( /^(canvas|textarea|input|select|button|img)$/i ) ) {
2928
2929
			this.element.wrap(
2930
				$( "<div class='ui-wrapper' style='overflow: hidden;'></div>" ).css( {
2931
					position: this.element.css( "position" ),
2932
					width: this.element.outerWidth(),
2933
					height: this.element.outerHeight(),
2934
					top: this.element.css( "top" ),
2935
					left: this.element.css( "left" )
2936
				} )
2937
			);
2938
2939
			this.element = this.element.parent().data(
2940
				"ui-resizable", this.element.resizable( "instance" )
2941
			);
2942
2943
			this.elementIsWrapper = true;
2944
2945
			margins = {
2946
				marginTop: this.originalElement.css( "marginTop" ),
2947
				marginRight: this.originalElement.css( "marginRight" ),
2948
				marginBottom: this.originalElement.css( "marginBottom" ),
2949
				marginLeft: this.originalElement.css( "marginLeft" )
2950
			};
2951
2952
			this.element.css( margins );
2953
			this.originalElement.css( "margin", 0 );
2954
2955
			// support: Safari
2956
			// Prevent Safari textarea resize
2957
			this.originalResizeStyle = this.originalElement.css( "resize" );
2958
			this.originalElement.css( "resize", "none" );
2959
2960
			this._proportionallyResizeElements.push( this.originalElement.css( {
2961
				position: "static",
2962
				zoom: 1,
2963
				display: "block"
2964
			} ) );
2965
2966
			// Support: IE9
2967
			// avoid IE jump (hard set the margin)
2968
			this.originalElement.css( margins );
2969
2970
			this._proportionallyResize();
2971
		}
2972
2973
		this._setupHandles();
2974
2975
		if ( o.autoHide ) {
2976
			$( this.element )
2977
				.on( "mouseenter", function() {
2978
					if ( o.disabled ) {
2979
						return;
2980
					}
2981
					that._removeClass( "ui-resizable-autohide" );
2982
					that._handles.show();
2983
				} )
2984
				.on( "mouseleave", function() {
2985
					if ( o.disabled ) {
2986
						return;
2987
					}
2988
					if ( !that.resizing ) {
2989
						that._addClass( "ui-resizable-autohide" );
2990
						that._handles.hide();
2991
					}
2992
				} );
2993
		}
2994
2995
		this._mouseInit();
2996
	},
2997
2998
	_destroy: function() {
2999
3000
		this._mouseDestroy();
3001
3002
		var wrapper,
3003
			_destroy = function( exp ) {
3004
				$( exp )
3005
					.removeData( "resizable" )
3006
					.removeData( "ui-resizable" )
3007
					.off( ".resizable" )
3008
					.find( ".ui-resizable-handle" )
3009
						.remove();
3010
			};
3011
3012
		// TODO: Unwrap at same DOM position
3013
		if ( this.elementIsWrapper ) {
3014
			_destroy( this.element );
3015
			wrapper = this.element;
3016
			this.originalElement.css( {
3017
				position: wrapper.css( "position" ),
3018
				width: wrapper.outerWidth(),
3019
				height: wrapper.outerHeight(),
3020
				top: wrapper.css( "top" ),
3021
				left: wrapper.css( "left" )
3022
			} ).insertAfter( wrapper );
3023
			wrapper.remove();
3024
		}
3025
3026
		this.originalElement.css( "resize", this.originalResizeStyle );
3027
		_destroy( this.originalElement );
3028
3029
		return this;
3030
	},
3031
3032
	_setOption: function( key, value ) {
3033
		this._super( key, value );
3034
3035
		switch ( key ) {
3036
		case "handles":
3037
			this._removeHandles();
3038
			this._setupHandles();
3039
			break;
3040
		default:
3041
			break;
3042
		}
3043
	},
3044
3045
	_setupHandles: function() {
3046
		var o = this.options, handle, i, n, hname, axis, that = this;
3047
		this.handles = o.handles ||
3048
			( !$( ".ui-resizable-handle", this.element ).length ?
3049
				"e,s,se" : {
3050
					n: ".ui-resizable-n",
3051
					e: ".ui-resizable-e",
3052
					s: ".ui-resizable-s",
3053
					w: ".ui-resizable-w",
3054
					se: ".ui-resizable-se",
3055
					sw: ".ui-resizable-sw",
3056
					ne: ".ui-resizable-ne",
3057
					nw: ".ui-resizable-nw"
3058
				} );
3059
3060
		this._handles = $();
3061
		if ( this.handles.constructor === String ) {
3062
3063
			if ( this.handles === "all" ) {
3064
				this.handles = "n,e,s,w,se,sw,ne,nw";
3065
			}
3066
3067
			n = this.handles.split( "," );
3068
			this.handles = {};
3069
3070
			for ( i = 0; i < n.length; i++ ) {
3071
3072
				handle = $.trim( n[ i ] );
3073
				hname = "ui-resizable-" + handle;
3074
				axis = $( "<div>" );
3075
				this._addClass( axis, "ui-resizable-handle " + hname );
3076
3077
				axis.css( { zIndex: o.zIndex } );
3078
3079
				this.handles[ handle ] = ".ui-resizable-" + handle;
3080
				this.element.append( axis );
3081
			}
3082
3083
		}
3084
3085
		this._renderAxis = function( target ) {
3086
3087
			var i, axis, padPos, padWrapper;
3088
3089
			target = target || this.element;
3090
3091
			for ( i in this.handles ) {
3092
3093
				if ( this.handles[ i ].constructor === String ) {
3094
					this.handles[ i ] = this.element.children( this.handles[ i ] ).first().show();
3095
				} else if ( this.handles[ i ].jquery || this.handles[ i ].nodeType ) {
3096
					this.handles[ i ] = $( this.handles[ i ] );
3097
					this._on( this.handles[ i ], { "mousedown": that._mouseDown } );
3098
				}
3099
3100
				if ( this.elementIsWrapper &&
3101
						this.originalElement[ 0 ]
3102
							.nodeName
3103
							.match( /^(textarea|input|select|button)$/i ) ) {
3104
					axis = $( this.handles[ i ], this.element );
3105
3106
					padWrapper = /sw|ne|nw|se|n|s/.test( i ) ?
3107
						axis.outerHeight() :
3108
						axis.outerWidth();
3109
3110
					padPos = [ "padding",
3111
						/ne|nw|n/.test( i ) ? "Top" :
3112
						/se|sw|s/.test( i ) ? "Bottom" :
3113
						/^e$/.test( i ) ? "Right" : "Left" ].join( "" );
3114
3115
					target.css( padPos, padWrapper );
3116
3117
					this._proportionallyResize();
3118
				}
3119
3120
				this._handles = this._handles.add( this.handles[ i ] );
3121
			}
3122
		};
3123
3124
		// TODO: make renderAxis a prototype function
3125
		this._renderAxis( this.element );
3126
3127
		this._handles = this._handles.add( this.element.find( ".ui-resizable-handle" ) );
3128
		this._handles.disableSelection();
3129
3130
		this._handles.on( "mouseover", function() {
3131
			if ( !that.resizing ) {
3132
				if ( this.className ) {
3133
					axis = this.className.match( /ui-resizable-(se|sw|ne|nw|n|e|s|w)/i );
3134
				}
3135
				that.axis = axis && axis[ 1 ] ? axis[ 1 ] : "se";
0 ignored issues
show
Bug introduced by
The variable axis seems to not be initialized for all possible execution paths.
Loading history...
3136
			}
3137
		} );
3138
3139
		if ( o.autoHide ) {
3140
			this._handles.hide();
3141
			this._addClass( "ui-resizable-autohide" );
3142
		}
3143
	},
3144
3145
	_removeHandles: function() {
3146
		this._handles.remove();
3147
	},
3148
3149
	_mouseCapture: function( event ) {
3150
		var i, handle,
3151
			capture = false;
3152
3153
		for ( i in this.handles ) {
3154
			handle = $( this.handles[ i ] )[ 0 ];
3155
			if ( handle === event.target || $.contains( handle, event.target ) ) {
3156
				capture = true;
3157
			}
3158
		}
3159
3160
		return !this.options.disabled && capture;
3161
	},
3162
3163
	_mouseStart: function( event ) {
3164
3165
		var curleft, curtop, cursor,
3166
			o = this.options,
3167
			el = this.element;
3168
3169
		this.resizing = true;
3170
3171
		this._renderProxy();
3172
3173
		curleft = this._num( this.helper.css( "left" ) );
3174
		curtop = this._num( this.helper.css( "top" ) );
3175
3176
		if ( o.containment ) {
3177
			curleft += $( o.containment ).scrollLeft() || 0;
3178
			curtop += $( o.containment ).scrollTop() || 0;
3179
		}
3180
3181
		this.offset = this.helper.offset();
3182
		this.position = { left: curleft, top: curtop };
3183
3184
		this.size = this._helper ? {
3185
				width: this.helper.width(),
3186
				height: this.helper.height()
3187
			} : {
3188
				width: el.width(),
3189
				height: el.height()
3190
			};
3191
3192
		this.originalSize = this._helper ? {
3193
				width: el.outerWidth(),
3194
				height: el.outerHeight()
3195
			} : {
3196
				width: el.width(),
3197
				height: el.height()
3198
			};
3199
3200
		this.sizeDiff = {
3201
			width: el.outerWidth() - el.width(),
3202
			height: el.outerHeight() - el.height()
3203
		};
3204
3205
		this.originalPosition = { left: curleft, top: curtop };
3206
		this.originalMousePosition = { left: event.pageX, top: event.pageY };
3207
3208
		this.aspectRatio = ( typeof o.aspectRatio === "number" ) ?
3209
			o.aspectRatio :
3210
			( ( this.originalSize.width / this.originalSize.height ) || 1 );
3211
3212
		cursor = $( ".ui-resizable-" + this.axis ).css( "cursor" );
3213
		$( "body" ).css( "cursor", cursor === "auto" ? this.axis + "-resize" : cursor );
3214
3215
		this._addClass( "ui-resizable-resizing" );
3216
		this._propagate( "start", event );
3217
		return true;
3218
	},
3219
3220
	_mouseDrag: function( event ) {
3221
3222
		var data, props,
3223
			smp = this.originalMousePosition,
3224
			a = this.axis,
3225
			dx = ( event.pageX - smp.left ) || 0,
3226
			dy = ( event.pageY - smp.top ) || 0,
3227
			trigger = this._change[ a ];
3228
3229
		this._updatePrevProperties();
3230
3231
		if ( !trigger ) {
3232
			return false;
3233
		}
3234
3235
		data = trigger.apply( this, [ event, dx, dy ] );
3236
3237
		this._updateVirtualBoundaries( event.shiftKey );
3238
		if ( this._aspectRatio || event.shiftKey ) {
3239
			data = this._updateRatio( data, event );
3240
		}
3241
3242
		data = this._respectSize( data, event );
3243
3244
		this._updateCache( data );
3245
3246
		this._propagate( "resize", event );
3247
3248
		props = this._applyChanges();
3249
3250
		if ( !this._helper && this._proportionallyResizeElements.length ) {
3251
			this._proportionallyResize();
3252
		}
3253
3254
		if ( !$.isEmptyObject( props ) ) {
3255
			this._updatePrevProperties();
3256
			this._trigger( "resize", event, this.ui() );
3257
			this._applyChanges();
3258
		}
3259
3260
		return false;
3261
	},
3262
3263
	_mouseStop: function( event ) {
3264
3265
		this.resizing = false;
3266
		var pr, ista, soffseth, soffsetw, s, left, top,
3267
			o = this.options, that = this;
3268
3269
		if ( this._helper ) {
3270
3271
			pr = this._proportionallyResizeElements;
3272
			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName );
3273
			soffseth = ista && this._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height;
3274
			soffsetw = ista ? 0 : that.sizeDiff.width;
3275
3276
			s = {
3277
				width: ( that.helper.width()  - soffsetw ),
3278
				height: ( that.helper.height() - soffseth )
3279
			};
3280
			left = ( parseFloat( that.element.css( "left" ) ) +
3281
				( that.position.left - that.originalPosition.left ) ) || null;
3282
			top = ( parseFloat( that.element.css( "top" ) ) +
3283
				( that.position.top - that.originalPosition.top ) ) || null;
3284
3285
			if ( !o.animate ) {
3286
				this.element.css( $.extend( s, { top: top, left: left } ) );
3287
			}
3288
3289
			that.helper.height( that.size.height );
3290
			that.helper.width( that.size.width );
3291
3292
			if ( this._helper && !o.animate ) {
3293
				this._proportionallyResize();
3294
			}
3295
		}
3296
3297
		$( "body" ).css( "cursor", "auto" );
3298
3299
		this._removeClass( "ui-resizable-resizing" );
3300
3301
		this._propagate( "stop", event );
3302
3303
		if ( this._helper ) {
3304
			this.helper.remove();
3305
		}
3306
3307
		return false;
3308
3309
	},
3310
3311
	_updatePrevProperties: function() {
3312
		this.prevPosition = {
3313
			top: this.position.top,
3314
			left: this.position.left
3315
		};
3316
		this.prevSize = {
3317
			width: this.size.width,
3318
			height: this.size.height
3319
		};
3320
	},
3321
3322
	_applyChanges: function() {
3323
		var props = {};
3324
3325
		if ( this.position.top !== this.prevPosition.top ) {
3326
			props.top = this.position.top + "px";
3327
		}
3328
		if ( this.position.left !== this.prevPosition.left ) {
3329
			props.left = this.position.left + "px";
3330
		}
3331
		if ( this.size.width !== this.prevSize.width ) {
3332
			props.width = this.size.width + "px";
3333
		}
3334
		if ( this.size.height !== this.prevSize.height ) {
3335
			props.height = this.size.height + "px";
3336
		}
3337
3338
		this.helper.css( props );
3339
3340
		return props;
3341
	},
3342
3343
	_updateVirtualBoundaries: function( forceAspectRatio ) {
3344
		var pMinWidth, pMaxWidth, pMinHeight, pMaxHeight, b,
3345
			o = this.options;
3346
3347
		b = {
3348
			minWidth: this._isNumber( o.minWidth ) ? o.minWidth : 0,
3349
			maxWidth: this._isNumber( o.maxWidth ) ? o.maxWidth : Infinity,
3350
			minHeight: this._isNumber( o.minHeight ) ? o.minHeight : 0,
3351
			maxHeight: this._isNumber( o.maxHeight ) ? o.maxHeight : Infinity
3352
		};
3353
3354
		if ( this._aspectRatio || forceAspectRatio ) {
3355
			pMinWidth = b.minHeight * this.aspectRatio;
3356
			pMinHeight = b.minWidth / this.aspectRatio;
3357
			pMaxWidth = b.maxHeight * this.aspectRatio;
3358
			pMaxHeight = b.maxWidth / this.aspectRatio;
3359
3360
			if ( pMinWidth > b.minWidth ) {
3361
				b.minWidth = pMinWidth;
3362
			}
3363
			if ( pMinHeight > b.minHeight ) {
3364
				b.minHeight = pMinHeight;
3365
			}
3366
			if ( pMaxWidth < b.maxWidth ) {
3367
				b.maxWidth = pMaxWidth;
3368
			}
3369
			if ( pMaxHeight < b.maxHeight ) {
3370
				b.maxHeight = pMaxHeight;
3371
			}
3372
		}
3373
		this._vBoundaries = b;
3374
	},
3375
3376
	_updateCache: function( data ) {
3377
		this.offset = this.helper.offset();
3378
		if ( this._isNumber( data.left ) ) {
3379
			this.position.left = data.left;
3380
		}
3381
		if ( this._isNumber( data.top ) ) {
3382
			this.position.top = data.top;
3383
		}
3384
		if ( this._isNumber( data.height ) ) {
3385
			this.size.height = data.height;
3386
		}
3387
		if ( this._isNumber( data.width ) ) {
3388
			this.size.width = data.width;
3389
		}
3390
	},
3391
3392
	_updateRatio: function( data ) {
3393
3394
		var cpos = this.position,
3395
			csize = this.size,
3396
			a = this.axis;
3397
3398
		if ( this._isNumber( data.height ) ) {
3399
			data.width = ( data.height * this.aspectRatio );
3400
		} else if ( this._isNumber( data.width ) ) {
3401
			data.height = ( data.width / this.aspectRatio );
3402
		}
3403
3404
		if ( a === "sw" ) {
3405
			data.left = cpos.left + ( csize.width - data.width );
3406
			data.top = null;
3407
		}
3408
		if ( a === "nw" ) {
3409
			data.top = cpos.top + ( csize.height - data.height );
3410
			data.left = cpos.left + ( csize.width - data.width );
3411
		}
3412
3413
		return data;
3414
	},
3415
3416
	_respectSize: function( data ) {
3417
3418
		var o = this._vBoundaries,
3419
			a = this.axis,
3420
			ismaxw = this._isNumber( data.width ) && o.maxWidth && ( o.maxWidth < data.width ),
3421
			ismaxh = this._isNumber( data.height ) && o.maxHeight && ( o.maxHeight < data.height ),
3422
			isminw = this._isNumber( data.width ) && o.minWidth && ( o.minWidth > data.width ),
3423
			isminh = this._isNumber( data.height ) && o.minHeight && ( o.minHeight > data.height ),
3424
			dw = this.originalPosition.left + this.originalSize.width,
3425
			dh = this.originalPosition.top + this.originalSize.height,
3426
			cw = /sw|nw|w/.test( a ), ch = /nw|ne|n/.test( a );
3427
		if ( isminw ) {
3428
			data.width = o.minWidth;
3429
		}
3430
		if ( isminh ) {
3431
			data.height = o.minHeight;
3432
		}
3433
		if ( ismaxw ) {
3434
			data.width = o.maxWidth;
3435
		}
3436
		if ( ismaxh ) {
3437
			data.height = o.maxHeight;
3438
		}
3439
3440
		if ( isminw && cw ) {
3441
			data.left = dw - o.minWidth;
3442
		}
3443
		if ( ismaxw && cw ) {
3444
			data.left = dw - o.maxWidth;
3445
		}
3446
		if ( isminh && ch ) {
3447
			data.top = dh - o.minHeight;
3448
		}
3449
		if ( ismaxh && ch ) {
3450
			data.top = dh - o.maxHeight;
3451
		}
3452
3453
		// Fixing jump error on top/left - bug #2330
3454
		if ( !data.width && !data.height && !data.left && data.top ) {
3455
			data.top = null;
3456
		} else if ( !data.width && !data.height && !data.top && data.left ) {
3457
			data.left = null;
3458
		}
3459
3460
		return data;
3461
	},
3462
3463
	_getPaddingPlusBorderDimensions: function( element ) {
3464
		var i = 0,
3465
			widths = [],
3466
			borders = [
3467
				element.css( "borderTopWidth" ),
3468
				element.css( "borderRightWidth" ),
3469
				element.css( "borderBottomWidth" ),
3470
				element.css( "borderLeftWidth" )
3471
			],
3472
			paddings = [
3473
				element.css( "paddingTop" ),
3474
				element.css( "paddingRight" ),
3475
				element.css( "paddingBottom" ),
3476
				element.css( "paddingLeft" )
3477
			];
3478
3479
		for ( ; i < 4; i++ ) {
3480
			widths[ i ] = ( parseFloat( borders[ i ] ) || 0 );
3481
			widths[ i ] += ( parseFloat( paddings[ i ] ) || 0 );
3482
		}
3483
3484
		return {
3485
			height: widths[ 0 ] + widths[ 2 ],
3486
			width: widths[ 1 ] + widths[ 3 ]
3487
		};
3488
	},
3489
3490
	_proportionallyResize: function() {
3491
3492
		if ( !this._proportionallyResizeElements.length ) {
3493
			return;
3494
		}
3495
3496
		var prel,
3497
			i = 0,
3498
			element = this.helper || this.element;
3499
3500
		for ( ; i < this._proportionallyResizeElements.length; i++ ) {
3501
3502
			prel = this._proportionallyResizeElements[ i ];
3503
3504
			// TODO: Seems like a bug to cache this.outerDimensions
3505
			// considering that we are in a loop.
3506
			if ( !this.outerDimensions ) {
3507
				this.outerDimensions = this._getPaddingPlusBorderDimensions( prel );
3508
			}
3509
3510
			prel.css( {
3511
				height: ( element.height() - this.outerDimensions.height ) || 0,
3512
				width: ( element.width() - this.outerDimensions.width ) || 0
3513
			} );
3514
3515
		}
3516
3517
	},
3518
3519
	_renderProxy: function() {
3520
3521
		var el = this.element, o = this.options;
3522
		this.elementOffset = el.offset();
3523
3524
		if ( this._helper ) {
3525
3526
			this.helper = this.helper || $( "<div style='overflow:hidden;'></div>" );
3527
3528
			this._addClass( this.helper, this._helper );
3529
			this.helper.css( {
3530
				width: this.element.outerWidth(),
3531
				height: this.element.outerHeight(),
3532
				position: "absolute",
3533
				left: this.elementOffset.left + "px",
3534
				top: this.elementOffset.top + "px",
3535
				zIndex: ++o.zIndex //TODO: Don't modify option
3536
			} );
3537
3538
			this.helper
3539
				.appendTo( "body" )
3540
				.disableSelection();
3541
3542
		} else {
3543
			this.helper = this.element;
3544
		}
3545
3546
	},
3547
3548
	_change: {
3549
		e: function( event, dx ) {
3550
			return { width: this.originalSize.width + dx };
3551
		},
3552
		w: function( event, dx ) {
3553
			var cs = this.originalSize, sp = this.originalPosition;
3554
			return { left: sp.left + dx, width: cs.width - dx };
3555
		},
3556
		n: function( event, dx, dy ) {
3557
			var cs = this.originalSize, sp = this.originalPosition;
3558
			return { top: sp.top + dy, height: cs.height - dy };
3559
		},
3560
		s: function( event, dx, dy ) {
3561
			return { height: this.originalSize.height + dy };
3562
		},
3563
		se: function( event, dx, dy ) {
3564
			return $.extend( this._change.s.apply( this, arguments ),
3565
				this._change.e.apply( this, [ event, dx, dy ] ) );
3566
		},
3567
		sw: function( event, dx, dy ) {
3568
			return $.extend( this._change.s.apply( this, arguments ),
3569
				this._change.w.apply( this, [ event, dx, dy ] ) );
3570
		},
3571
		ne: function( event, dx, dy ) {
3572
			return $.extend( this._change.n.apply( this, arguments ),
3573
				this._change.e.apply( this, [ event, dx, dy ] ) );
3574
		},
3575
		nw: function( event, dx, dy ) {
3576
			return $.extend( this._change.n.apply( this, arguments ),
3577
				this._change.w.apply( this, [ event, dx, dy ] ) );
3578
		}
3579
	},
3580
3581
	_propagate: function( n, event ) {
3582
		$.ui.plugin.call( this, n, [ event, this.ui() ] );
3583
		( n !== "resize" && this._trigger( n, event, this.ui() ) );
3584
	},
3585
3586
	plugins: {},
3587
3588
	ui: function() {
3589
		return {
3590
			originalElement: this.originalElement,
3591
			element: this.element,
3592
			helper: this.helper,
3593
			position: this.position,
3594
			size: this.size,
3595
			originalSize: this.originalSize,
3596
			originalPosition: this.originalPosition
3597
		};
3598
	}
3599
3600
} );
3601
3602
/*
3603
 * Resizable Extensions
3604
 */
3605
3606
$.ui.plugin.add( "resizable", "animate", {
3607
3608
	stop: function( event ) {
3609
		var that = $( this ).resizable( "instance" ),
3610
			o = that.options,
3611
			pr = that._proportionallyResizeElements,
3612
			ista = pr.length && ( /textarea/i ).test( pr[ 0 ].nodeName ),
3613
			soffseth = ista && that._hasScroll( pr[ 0 ], "left" ) ? 0 : that.sizeDiff.height,
3614
			soffsetw = ista ? 0 : that.sizeDiff.width,
3615
			style = {
3616
				width: ( that.size.width - soffsetw ),
3617
				height: ( that.size.height - soffseth )
3618
			},
3619
			left = ( parseFloat( that.element.css( "left" ) ) +
3620
				( that.position.left - that.originalPosition.left ) ) || null,
3621
			top = ( parseFloat( that.element.css( "top" ) ) +
3622
				( that.position.top - that.originalPosition.top ) ) || null;
3623
3624
		that.element.animate(
3625
			$.extend( style, top && left ? { top: top, left: left } : {} ), {
3626
				duration: o.animateDuration,
3627
				easing: o.animateEasing,
3628
				step: function() {
3629
3630
					var data = {
3631
						width: parseFloat( that.element.css( "width" ) ),
3632
						height: parseFloat( that.element.css( "height" ) ),
3633
						top: parseFloat( that.element.css( "top" ) ),
3634
						left: parseFloat( that.element.css( "left" ) )
3635
					};
3636
3637
					if ( pr && pr.length ) {
3638
						$( pr[ 0 ] ).css( { width: data.width, height: data.height } );
3639
					}
3640
3641
					// Propagating resize, and updating values for each animation step
3642
					that._updateCache( data );
3643
					that._propagate( "resize", event );
3644
3645
				}
3646
			}
3647
		);
3648
	}
3649
3650
} );
3651
3652
$.ui.plugin.add( "resizable", "containment", {
3653
3654
	start: function() {
3655
		var element, p, co, ch, cw, width, height,
3656
			that = $( this ).resizable( "instance" ),
3657
			o = that.options,
3658
			el = that.element,
3659
			oc = o.containment,
3660
			ce = ( oc instanceof $ ) ?
3661
				oc.get( 0 ) :
3662
				( /parent/.test( oc ) ) ? el.parent().get( 0 ) : oc;
3663
3664
		if ( !ce ) {
3665
			return;
3666
		}
3667
3668
		that.containerElement = $( ce );
3669
3670
		if ( /document/.test( oc ) || oc === document ) {
3671
			that.containerOffset = {
3672
				left: 0,
3673
				top: 0
3674
			};
3675
			that.containerPosition = {
3676
				left: 0,
3677
				top: 0
3678
			};
3679
3680
			that.parentData = {
3681
				element: $( document ),
3682
				left: 0,
3683
				top: 0,
3684
				width: $( document ).width(),
3685
				height: $( document ).height() || document.body.parentNode.scrollHeight
3686
			};
3687
		} else {
3688
			element = $( ce );
3689
			p = [];
3690
			$( [ "Top", "Right", "Left", "Bottom" ] ).each( function( i, name ) {
3691
				p[ i ] = that._num( element.css( "padding" + name ) );
3692
			} );
3693
3694
			that.containerOffset = element.offset();
3695
			that.containerPosition = element.position();
3696
			that.containerSize = {
3697
				height: ( element.innerHeight() - p[ 3 ] ),
3698
				width: ( element.innerWidth() - p[ 1 ] )
3699
			};
3700
3701
			co = that.containerOffset;
3702
			ch = that.containerSize.height;
3703
			cw = that.containerSize.width;
3704
			width = ( that._hasScroll ( ce, "left" ) ? ce.scrollWidth : cw );
3705
			height = ( that._hasScroll ( ce ) ? ce.scrollHeight : ch ) ;
3706
3707
			that.parentData = {
3708
				element: ce,
3709
				left: co.left,
3710
				top: co.top,
3711
				width: width,
3712
				height: height
3713
			};
3714
		}
3715
	},
3716
3717
	resize: function( event ) {
3718
		var woset, hoset, isParent, isOffsetRelative,
3719
			that = $( this ).resizable( "instance" ),
3720
			o = that.options,
3721
			co = that.containerOffset,
3722
			cp = that.position,
3723
			pRatio = that._aspectRatio || event.shiftKey,
3724
			cop = {
3725
				top: 0,
3726
				left: 0
3727
			},
3728
			ce = that.containerElement,
3729
			continueResize = true;
3730
3731
		if ( ce[ 0 ] !== document && ( /static/ ).test( ce.css( "position" ) ) ) {
3732
			cop = co;
3733
		}
3734
3735
		if ( cp.left < ( that._helper ? co.left : 0 ) ) {
3736
			that.size.width = that.size.width +
3737
				( that._helper ?
3738
					( that.position.left - co.left ) :
3739
					( that.position.left - cop.left ) );
3740
3741
			if ( pRatio ) {
3742
				that.size.height = that.size.width / that.aspectRatio;
3743
				continueResize = false;
3744
			}
3745
			that.position.left = o.helper ? co.left : 0;
3746
		}
3747
3748
		if ( cp.top < ( that._helper ? co.top : 0 ) ) {
3749
			that.size.height = that.size.height +
3750
				( that._helper ?
3751
					( that.position.top - co.top ) :
3752
					that.position.top );
3753
3754
			if ( pRatio ) {
3755
				that.size.width = that.size.height * that.aspectRatio;
3756
				continueResize = false;
3757
			}
3758
			that.position.top = that._helper ? co.top : 0;
3759
		}
3760
3761
		isParent = that.containerElement.get( 0 ) === that.element.parent().get( 0 );
3762
		isOffsetRelative = /relative|absolute/.test( that.containerElement.css( "position" ) );
3763
3764
		if ( isParent && isOffsetRelative ) {
3765
			that.offset.left = that.parentData.left + that.position.left;
3766
			that.offset.top = that.parentData.top + that.position.top;
3767
		} else {
3768
			that.offset.left = that.element.offset().left;
3769
			that.offset.top = that.element.offset().top;
3770
		}
3771
3772
		woset = Math.abs( that.sizeDiff.width +
3773
			( that._helper ?
3774
				that.offset.left - cop.left :
3775
				( that.offset.left - co.left ) ) );
3776
3777
		hoset = Math.abs( that.sizeDiff.height +
3778
			( that._helper ?
3779
				that.offset.top - cop.top :
3780
				( that.offset.top - co.top ) ) );
3781
3782
		if ( woset + that.size.width >= that.parentData.width ) {
3783
			that.size.width = that.parentData.width - woset;
3784
			if ( pRatio ) {
3785
				that.size.height = that.size.width / that.aspectRatio;
3786
				continueResize = false;
3787
			}
3788
		}
3789
3790
		if ( hoset + that.size.height >= that.parentData.height ) {
3791
			that.size.height = that.parentData.height - hoset;
3792
			if ( pRatio ) {
3793
				that.size.width = that.size.height * that.aspectRatio;
3794
				continueResize = false;
3795
			}
3796
		}
3797
3798
		if ( !continueResize ) {
3799
			that.position.left = that.prevPosition.left;
3800
			that.position.top = that.prevPosition.top;
3801
			that.size.width = that.prevSize.width;
3802
			that.size.height = that.prevSize.height;
3803
		}
3804
	},
3805
3806
	stop: function() {
3807
		var that = $( this ).resizable( "instance" ),
3808
			o = that.options,
3809
			co = that.containerOffset,
3810
			cop = that.containerPosition,
3811
			ce = that.containerElement,
3812
			helper = $( that.helper ),
3813
			ho = helper.offset(),
3814
			w = helper.outerWidth() - that.sizeDiff.width,
3815
			h = helper.outerHeight() - that.sizeDiff.height;
3816
3817
		if ( that._helper && !o.animate && ( /relative/ ).test( ce.css( "position" ) ) ) {
3818
			$( this ).css( {
3819
				left: ho.left - cop.left - co.left,
3820
				width: w,
3821
				height: h
3822
			} );
3823
		}
3824
3825
		if ( that._helper && !o.animate && ( /static/ ).test( ce.css( "position" ) ) ) {
3826
			$( this ).css( {
3827
				left: ho.left - cop.left - co.left,
3828
				width: w,
3829
				height: h
3830
			} );
3831
		}
3832
	}
3833
} );
3834
3835
$.ui.plugin.add( "resizable", "alsoResize", {
3836
3837
	start: function() {
3838
		var that = $( this ).resizable( "instance" ),
3839
			o = that.options;
3840
3841
		$( o.alsoResize ).each( function() {
3842
			var el = $( this );
3843
			el.data( "ui-resizable-alsoresize", {
3844
				width: parseFloat( el.width() ), height: parseFloat( el.height() ),
3845
				left: parseFloat( el.css( "left" ) ), top: parseFloat( el.css( "top" ) )
3846
			} );
3847
		} );
3848
	},
3849
3850
	resize: function( event, ui ) {
3851
		var that = $( this ).resizable( "instance" ),
3852
			o = that.options,
3853
			os = that.originalSize,
3854
			op = that.originalPosition,
3855
			delta = {
3856
				height: ( that.size.height - os.height ) || 0,
3857
				width: ( that.size.width - os.width ) || 0,
3858
				top: ( that.position.top - op.top ) || 0,
3859
				left: ( that.position.left - op.left ) || 0
3860
			};
3861
3862
			$( o.alsoResize ).each( function() {
3863
				var el = $( this ), start = $( this ).data( "ui-resizable-alsoresize" ), style = {},
3864
					css = el.parents( ui.originalElement[ 0 ] ).length ?
3865
							[ "width", "height" ] :
3866
							[ "width", "height", "top", "left" ];
3867
3868
				$.each( css, function( i, prop ) {
3869
					var sum = ( start[ prop ] || 0 ) + ( delta[ prop ] || 0 );
3870
					if ( sum && sum >= 0 ) {
3871
						style[ prop ] = sum || null;
3872
					}
3873
				} );
3874
3875
				el.css( style );
3876
			} );
3877
	},
3878
3879
	stop: function() {
3880
		$( this ).removeData( "ui-resizable-alsoresize" );
3881
	}
3882
} );
3883
3884
$.ui.plugin.add( "resizable", "ghost", {
3885
3886
	start: function() {
3887
3888
		var that = $( this ).resizable( "instance" ), cs = that.size;
3889
3890
		that.ghost = that.originalElement.clone();
3891
		that.ghost.css( {
3892
			opacity: 0.25,
3893
			display: "block",
3894
			position: "relative",
3895
			height: cs.height,
3896
			width: cs.width,
3897
			margin: 0,
3898
			left: 0,
3899
			top: 0
3900
		} );
3901
3902
		that._addClass( that.ghost, "ui-resizable-ghost" );
3903
3904
		// DEPRECATED
3905
		// TODO: remove after 1.12
3906
		if ( $.uiBackCompat !== false && typeof that.options.ghost === "string" ) {
3907
3908
			// Ghost option
3909
			that.ghost.addClass( this.options.ghost );
3910
		}
3911
3912
		that.ghost.appendTo( that.helper );
3913
3914
	},
3915
3916
	resize: function() {
3917
		var that = $( this ).resizable( "instance" );
3918
		if ( that.ghost ) {
3919
			that.ghost.css( {
3920
				position: "relative",
3921
				height: that.size.height,
3922
				width: that.size.width
3923
			} );
3924
		}
3925
	},
3926
3927
	stop: function() {
3928
		var that = $( this ).resizable( "instance" );
3929
		if ( that.ghost && that.helper ) {
3930
			that.helper.get( 0 ).removeChild( that.ghost.get( 0 ) );
3931
		}
3932
	}
3933
3934
} );
3935
3936
$.ui.plugin.add( "resizable", "grid", {
3937
3938
	resize: function() {
3939
		var outerDimensions,
3940
			that = $( this ).resizable( "instance" ),
3941
			o = that.options,
3942
			cs = that.size,
3943
			os = that.originalSize,
3944
			op = that.originalPosition,
3945
			a = that.axis,
3946
			grid = typeof o.grid === "number" ? [ o.grid, o.grid ] : o.grid,
3947
			gridX = ( grid[ 0 ] || 1 ),
3948
			gridY = ( grid[ 1 ] || 1 ),
3949
			ox = Math.round( ( cs.width - os.width ) / gridX ) * gridX,
3950
			oy = Math.round( ( cs.height - os.height ) / gridY ) * gridY,
3951
			newWidth = os.width + ox,
3952
			newHeight = os.height + oy,
3953
			isMaxWidth = o.maxWidth && ( o.maxWidth < newWidth ),
3954
			isMaxHeight = o.maxHeight && ( o.maxHeight < newHeight ),
3955
			isMinWidth = o.minWidth && ( o.minWidth > newWidth ),
3956
			isMinHeight = o.minHeight && ( o.minHeight > newHeight );
3957
3958
		o.grid = grid;
3959
3960
		if ( isMinWidth ) {
3961
			newWidth += gridX;
3962
		}
3963
		if ( isMinHeight ) {
3964
			newHeight += gridY;
3965
		}
3966
		if ( isMaxWidth ) {
3967
			newWidth -= gridX;
3968
		}
3969
		if ( isMaxHeight ) {
3970
			newHeight -= gridY;
3971
		}
3972
3973
		if ( /^(se|s|e)$/.test( a ) ) {
3974
			that.size.width = newWidth;
3975
			that.size.height = newHeight;
3976
		} else if ( /^(ne)$/.test( a ) ) {
3977
			that.size.width = newWidth;
3978
			that.size.height = newHeight;
3979
			that.position.top = op.top - oy;
3980
		} else if ( /^(sw)$/.test( a ) ) {
3981
			that.size.width = newWidth;
3982
			that.size.height = newHeight;
3983
			that.position.left = op.left - ox;
3984
		} else {
3985
			if ( newHeight - gridY <= 0 || newWidth - gridX <= 0 ) {
3986
				outerDimensions = that._getPaddingPlusBorderDimensions( this );
3987
			}
3988
3989
			if ( newHeight - gridY > 0 ) {
3990
				that.size.height = newHeight;
3991
				that.position.top = op.top - oy;
3992
			} else {
3993
				newHeight = gridY - outerDimensions.height;
0 ignored issues
show
Bug introduced by
The variable outerDimensions does not seem to be initialized in case newHeight - gridY <= 0 || newWidth - gridX <= 0 on line 3985 is false. Are you sure this can never be the case?
Loading history...
3994
				that.size.height = newHeight;
3995
				that.position.top = op.top + os.height - newHeight;
3996
			}
3997
			if ( newWidth - gridX > 0 ) {
3998
				that.size.width = newWidth;
3999
				that.position.left = op.left - ox;
4000
			} else {
4001
				newWidth = gridX - outerDimensions.width;
4002
				that.size.width = newWidth;
4003
				that.position.left = op.left + os.width - newWidth;
4004
			}
4005
		}
4006
	}
4007
4008
} );
4009
4010
var widgetsResizable = $.ui.resizable;
0 ignored issues
show
Unused Code introduced by
The variable widgetsResizable seems to be never used. Consider removing it.
Loading history...
4011
4012
4013
/*!
4014
 * jQuery UI Selectable 1.12.0
4015
 * http://jqueryui.com
4016
 *
4017
 * Copyright jQuery Foundation and other contributors
4018
 * Released under the MIT license.
4019
 * http://jquery.org/license
4020
 */
4021
4022
//>>label: Selectable
4023
//>>group: Interactions
4024
//>>description: Allows groups of elements to be selected with the mouse.
4025
//>>docs: http://api.jqueryui.com/selectable/
4026
//>>demos: http://jqueryui.com/selectable/
4027
//>>css.structure: ../../themes/base/selectable.css
4028
4029
4030
4031
var widgetsSelectable = $.widget( "ui.selectable", $.ui.mouse, {
0 ignored issues
show
Unused Code introduced by
The variable widgetsSelectable seems to be never used. Consider removing it.
Loading history...
4032
	version: "1.12.0",
4033
	options: {
4034
		appendTo: "body",
4035
		autoRefresh: true,
4036
		distance: 0,
4037
		filter: "*",
4038
		tolerance: "touch",
4039
4040
		// Callbacks
4041
		selected: null,
4042
		selecting: null,
4043
		start: null,
4044
		stop: null,
4045
		unselected: null,
4046
		unselecting: null
4047
	},
4048
	_create: function() {
4049
		var that = this;
4050
4051
		this._addClass( "ui-selectable" );
4052
4053
		this.dragged = false;
4054
4055
		// Cache selectee children based on filter
4056
		this.refresh = function() {
4057
			that.elementPos = $( that.element[ 0 ] ).offset();
4058
			that.selectees = $( that.options.filter, that.element[ 0 ] );
4059
			that._addClass( that.selectees, "ui-selectee" );
4060
			that.selectees.each( function() {
4061
				var $this = $( this ),
4062
					selecteeOffset = $this.offset(),
4063
					pos = {
4064
						left: selecteeOffset.left - that.elementPos.left,
4065
						top: selecteeOffset.top - that.elementPos.top
4066
					};
4067
				$.data( this, "selectable-item", {
4068
					element: this,
4069
					$element: $this,
4070
					left: pos.left,
4071
					top: pos.top,
4072
					right: pos.left + $this.outerWidth(),
4073
					bottom: pos.top + $this.outerHeight(),
4074
					startselected: false,
4075
					selected: $this.hasClass( "ui-selected" ),
4076
					selecting: $this.hasClass( "ui-selecting" ),
4077
					unselecting: $this.hasClass( "ui-unselecting" )
4078
				} );
4079
			} );
4080
		};
4081
		this.refresh();
4082
4083
		this._mouseInit();
4084
4085
		this.helper = $( "<div>" );
4086
		this._addClass( this.helper, "ui-selectable-helper" );
4087
	},
4088
4089
	_destroy: function() {
4090
		this.selectees.removeData( "selectable-item" );
4091
		this._mouseDestroy();
4092
	},
4093
4094
	_mouseStart: function( event ) {
4095
		var that = this,
4096
			options = this.options;
4097
4098
		this.opos = [ event.pageX, event.pageY ];
4099
		this.elementPos = $( this.element[ 0 ] ).offset();
4100
4101
		if ( this.options.disabled ) {
4102
			return;
4103
		}
4104
4105
		this.selectees = $( options.filter, this.element[ 0 ] );
4106
4107
		this._trigger( "start", event );
4108
4109
		$( options.appendTo ).append( this.helper );
4110
4111
		// position helper (lasso)
4112
		this.helper.css( {
4113
			"left": event.pageX,
4114
			"top": event.pageY,
4115
			"width": 0,
4116
			"height": 0
4117
		} );
4118
4119
		if ( options.autoRefresh ) {
4120
			this.refresh();
4121
		}
4122
4123
		this.selectees.filter( ".ui-selected" ).each( function() {
4124
			var selectee = $.data( this, "selectable-item" );
4125
			selectee.startselected = true;
4126
			if ( !event.metaKey && !event.ctrlKey ) {
4127
				that._removeClass( selectee.$element, "ui-selected" );
4128
				selectee.selected = false;
4129
				that._addClass( selectee.$element, "ui-unselecting" );
4130
				selectee.unselecting = true;
4131
4132
				// selectable UNSELECTING callback
4133
				that._trigger( "unselecting", event, {
4134
					unselecting: selectee.element
4135
				} );
4136
			}
4137
		} );
4138
4139
		$( event.target ).parents().addBack().each( function() {
4140
			var doSelect,
4141
				selectee = $.data( this, "selectable-item" );
4142
			if ( selectee ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if selectee 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...
4143
				doSelect = ( !event.metaKey && !event.ctrlKey ) ||
4144
					!selectee.$element.hasClass( "ui-selected" );
4145
				that._removeClass( selectee.$element, doSelect ? "ui-unselecting" : "ui-selected" )
4146
					._addClass( selectee.$element, doSelect ? "ui-selecting" : "ui-unselecting" );
4147
				selectee.unselecting = !doSelect;
4148
				selectee.selecting = doSelect;
4149
				selectee.selected = doSelect;
4150
4151
				// selectable (UN)SELECTING callback
4152
				if ( doSelect ) {
4153
					that._trigger( "selecting", event, {
4154
						selecting: selectee.element
4155
					} );
4156
				} else {
4157
					that._trigger( "unselecting", event, {
4158
						unselecting: selectee.element
4159
					} );
4160
				}
4161
				return false;
4162
			}
4163
		} );
4164
4165
	},
4166
4167
	_mouseDrag: function( event ) {
4168
4169
		this.dragged = true;
4170
4171
		if ( this.options.disabled ) {
4172
			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...
4173
		}
4174
4175
		var tmp,
4176
			that = this,
4177
			options = this.options,
4178
			x1 = this.opos[ 0 ],
4179
			y1 = this.opos[ 1 ],
4180
			x2 = event.pageX,
4181
			y2 = event.pageY;
4182
4183
		if ( x1 > x2 ) { tmp = x2; x2 = x1; x1 = tmp; }
4184
		if ( y1 > y2 ) { tmp = y2; y2 = y1; y1 = tmp; }
4185
		this.helper.css( { left: x1, top: y1, width: x2 - x1, height: y2 - y1 } );
4186
4187
		this.selectees.each( function() {
4188
			var selectee = $.data( this, "selectable-item" ),
4189
				hit = false,
4190
				offset = {};
4191
4192
			//prevent helper from being selected if appendTo: selectable
4193
			if ( !selectee || selectee.element === that.element[ 0 ] ) {
4194
				return;
4195
			}
4196
4197
			offset.left   = selectee.left   + that.elementPos.left;
4198
			offset.right  = selectee.right  + that.elementPos.left;
4199
			offset.top    = selectee.top    + that.elementPos.top;
4200
			offset.bottom = selectee.bottom + that.elementPos.top;
4201
4202
			if ( options.tolerance === "touch" ) {
4203
				hit = ( !( offset.left > x2 || offset.right < x1 || offset.top > y2 ||
4204
                    offset.bottom < y1 ) );
4205
			} else if ( options.tolerance === "fit" ) {
4206
				hit = ( offset.left > x1 && offset.right < x2 && offset.top > y1 &&
4207
                    offset.bottom < y2 );
4208
			}
4209
4210
			if ( hit ) {
4211
4212
				// SELECT
4213
				if ( selectee.selected ) {
4214
					that._removeClass( selectee.$element, "ui-selected" );
4215
					selectee.selected = false;
4216
				}
4217
				if ( selectee.unselecting ) {
4218
					that._removeClass( selectee.$element, "ui-unselecting" );
4219
					selectee.unselecting = false;
4220
				}
4221
				if ( !selectee.selecting ) {
4222
					that._addClass( selectee.$element, "ui-selecting" );
4223
					selectee.selecting = true;
4224
4225
					// selectable SELECTING callback
4226
					that._trigger( "selecting", event, {
4227
						selecting: selectee.element
4228
					} );
4229
				}
4230
			} else {
4231
4232
				// UNSELECT
4233
				if ( selectee.selecting ) {
4234
					if ( ( event.metaKey || event.ctrlKey ) && selectee.startselected ) {
4235
						that._removeClass( selectee.$element, "ui-selecting" );
4236
						selectee.selecting = false;
4237
						that._addClass( selectee.$element, "ui-selected" );
4238
						selectee.selected = true;
4239
					} else {
4240
						that._removeClass( selectee.$element, "ui-selecting" );
4241
						selectee.selecting = false;
4242
						if ( selectee.startselected ) {
4243
							that._addClass( selectee.$element, "ui-unselecting" );
4244
							selectee.unselecting = true;
4245
						}
4246
4247
						// selectable UNSELECTING callback
4248
						that._trigger( "unselecting", event, {
4249
							unselecting: selectee.element
4250
						} );
4251
					}
4252
				}
4253
				if ( selectee.selected ) {
4254
					if ( !event.metaKey && !event.ctrlKey && !selectee.startselected ) {
4255
						that._removeClass( selectee.$element, "ui-selected" );
4256
						selectee.selected = false;
4257
4258
						that._addClass( selectee.$element, "ui-unselecting" );
4259
						selectee.unselecting = true;
4260
4261
						// selectable UNSELECTING callback
4262
						that._trigger( "unselecting", event, {
4263
							unselecting: selectee.element
4264
						} );
4265
					}
4266
				}
4267
			}
4268
		} );
4269
4270
		return false;
4271
	},
4272
4273
	_mouseStop: function( event ) {
4274
		var that = this;
4275
4276
		this.dragged = false;
4277
4278
		$( ".ui-unselecting", this.element[ 0 ] ).each( function() {
4279
			var selectee = $.data( this, "selectable-item" );
4280
			that._removeClass( selectee.$element, "ui-unselecting" );
4281
			selectee.unselecting = false;
4282
			selectee.startselected = false;
4283
			that._trigger( "unselected", event, {
4284
				unselected: selectee.element
4285
			} );
4286
		} );
4287
		$( ".ui-selecting", this.element[ 0 ] ).each( function() {
4288
			var selectee = $.data( this, "selectable-item" );
4289
			that._removeClass( selectee.$element, "ui-selecting" )
4290
				._addClass( selectee.$element, "ui-selected" );
4291
			selectee.selecting = false;
4292
			selectee.selected = true;
4293
			selectee.startselected = true;
4294
			that._trigger( "selected", event, {
4295
				selected: selectee.element
4296
			} );
4297
		} );
4298
		this._trigger( "stop", event );
4299
4300
		this.helper.remove();
4301
4302
		return false;
4303
	}
4304
4305
} );
4306
4307
4308
/*!
4309
 * jQuery UI Sortable 1.12.0
4310
 * http://jqueryui.com
4311
 *
4312
 * Copyright jQuery Foundation and other contributors
4313
 * Released under the MIT license.
4314
 * http://jquery.org/license
4315
 */
4316
4317
//>>label: Sortable
4318
//>>group: Interactions
4319
//>>description: Enables items in a list to be sorted using the mouse.
4320
//>>docs: http://api.jqueryui.com/sortable/
4321
//>>demos: http://jqueryui.com/sortable/
4322
//>>css.structure: ../../themes/base/sortable.css
4323
4324
4325
4326
var widgetsSortable = $.widget( "ui.sortable", $.ui.mouse, {
0 ignored issues
show
Unused Code introduced by
The variable widgetsSortable seems to be never used. Consider removing it.
Loading history...
4327
	version: "1.12.0",
4328
	widgetEventPrefix: "sort",
4329
	ready: false,
4330
	options: {
4331
		appendTo: "parent",
4332
		axis: false,
4333
		connectWith: false,
4334
		containment: false,
4335
		cursor: "auto",
4336
		cursorAt: false,
4337
		dropOnEmpty: true,
4338
		forcePlaceholderSize: false,
4339
		forceHelperSize: false,
4340
		grid: false,
4341
		handle: false,
4342
		helper: "original",
4343
		items: "> *",
4344
		opacity: false,
4345
		placeholder: false,
4346
		revert: false,
4347
		scroll: true,
4348
		scrollSensitivity: 20,
4349
		scrollSpeed: 20,
4350
		scope: "default",
4351
		tolerance: "intersect",
4352
		zIndex: 1000,
4353
4354
		// Callbacks
4355
		activate: null,
4356
		beforeStop: null,
4357
		change: null,
4358
		deactivate: null,
4359
		out: null,
4360
		over: null,
4361
		receive: null,
4362
		remove: null,
4363
		sort: null,
4364
		start: null,
4365
		stop: null,
4366
		update: null
4367
	},
4368
4369
	_isOverAxis: function( x, reference, size ) {
4370
		return ( x >= reference ) && ( x < ( reference + size ) );
4371
	},
4372
4373
	_isFloating: function( item ) {
4374
		return ( /left|right/ ).test( item.css( "float" ) ) ||
4375
			( /inline|table-cell/ ).test( item.css( "display" ) );
4376
	},
4377
4378
	_create: function() {
4379
		this.containerCache = {};
4380
		this._addClass( "ui-sortable" );
4381
4382
		//Get the items
4383
		this.refresh();
4384
4385
		//Let's determine the parent's offset
4386
		this.offset = this.element.offset();
4387
4388
		//Initialize mouse events for interaction
4389
		this._mouseInit();
4390
4391
		this._setHandleClassName();
4392
4393
		//We're ready to go
4394
		this.ready = true;
4395
4396
	},
4397
4398
	_setOption: function( key, value ) {
4399
		this._super( key, value );
4400
4401
		if ( key === "handle" ) {
4402
			this._setHandleClassName();
4403
		}
4404
	},
4405
4406
	_setHandleClassName: function() {
4407
		var that = this;
4408
		this._removeClass( this.element.find( ".ui-sortable-handle" ), "ui-sortable-handle" );
4409
		$.each( this.items, function() {
4410
			that._addClass(
4411
				this.instance.options.handle ?
4412
					this.item.find( this.instance.options.handle ) :
4413
					this.item,
4414
				"ui-sortable-handle"
4415
			);
4416
		} );
4417
	},
4418
4419
	_destroy: function() {
4420
		this._mouseDestroy();
4421
4422
		for ( var i = this.items.length - 1; i >= 0; i-- ) {
4423
			this.items[ i ].item.removeData( this.widgetName + "-item" );
4424
		}
4425
4426
		return this;
4427
	},
4428
4429
	_mouseCapture: function( event, overrideHandle ) {
4430
		var currentItem = null,
4431
			validHandle = false,
4432
			that = this;
4433
4434
		if ( this.reverting ) {
4435
			return false;
4436
		}
4437
4438
		if ( this.options.disabled || this.options.type === "static" ) {
4439
			return false;
4440
		}
4441
4442
		//We have to refresh the items data once first
4443
		this._refreshItems( event );
4444
4445
		//Find out if the clicked node (or one of its parents) is a actual item in this.items
4446
		$( event.target ).parents().each( function() {
4447
			if ( $.data( this, that.widgetName + "-item" ) === that ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if $.data(this, that.widgetName + "-item") === that 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...
4448
				currentItem = $( this );
4449
				return false;
4450
			}
4451
		} );
4452
		if ( $.data( event.target, that.widgetName + "-item" ) === that ) {
4453
			currentItem = $( event.target );
4454
		}
4455
4456
		if ( !currentItem ) {
4457
			return false;
4458
		}
4459
		if ( this.options.handle && !overrideHandle ) {
4460
			$( this.options.handle, currentItem ).find( "*" ).addBack().each( function() {
4461
				if ( this === event.target ) {
4462
					validHandle = true;
4463
				}
4464
			} );
4465
			if ( !validHandle ) {
4466
				return false;
4467
			}
4468
		}
4469
4470
		this.currentItem = currentItem;
4471
		this._removeCurrentsFromItems();
4472
		return true;
4473
4474
	},
4475
4476
	_mouseStart: function( event, overrideHandle, noActivation ) {
4477
4478
		var i, body,
4479
			o = this.options;
4480
4481
		this.currentContainer = this;
4482
4483
		//We only need to call refreshPositions, because the refreshItems call has been moved to
4484
		// mouseCapture
4485
		this.refreshPositions();
4486
4487
		//Create and append the visible helper
4488
		this.helper = this._createHelper( event );
4489
4490
		//Cache the helper size
4491
		this._cacheHelperProportions();
4492
4493
		/*
4494
		 * - Position generation -
4495
		 * This block generates everything position related - it's the core of draggables.
4496
		 */
4497
4498
		//Cache the margins of the original element
4499
		this._cacheMargins();
4500
4501
		//Get the next scrolling parent
4502
		this.scrollParent = this.helper.scrollParent();
4503
4504
		//The element's absolute position on the page minus margins
4505
		this.offset = this.currentItem.offset();
4506
		this.offset = {
4507
			top: this.offset.top - this.margins.top,
4508
			left: this.offset.left - this.margins.left
4509
		};
4510
4511
		$.extend( this.offset, {
4512
			click: { //Where the click happened, relative to the element
4513
				left: event.pageX - this.offset.left,
4514
				top: event.pageY - this.offset.top
4515
			},
4516
			parent: this._getParentOffset(),
4517
4518
			// This is a relative to absolute position minus the actual position calculation -
4519
			// only used for relative positioned helper
4520
			relative: this._getRelativeOffset()
4521
		} );
4522
4523
		// Only after we got the offset, we can change the helper's position to absolute
4524
		// TODO: Still need to figure out a way to make relative sorting possible
4525
		this.helper.css( "position", "absolute" );
4526
		this.cssPosition = this.helper.css( "position" );
4527
4528
		//Generate the original position
4529
		this.originalPosition = this._generatePosition( event );
4530
		this.originalPageX = event.pageX;
4531
		this.originalPageY = event.pageY;
4532
4533
		//Adjust the mouse offset relative to the helper if "cursorAt" is supplied
4534
		( o.cursorAt && this._adjustOffsetFromHelper( o.cursorAt ) );
4535
4536
		//Cache the former DOM position
4537
		this.domPosition = {
4538
			prev: this.currentItem.prev()[ 0 ],
4539
			parent: this.currentItem.parent()[ 0 ]
4540
		};
4541
4542
		// If the helper is not the original, hide the original so it's not playing any role during
4543
		// the drag, won't cause anything bad this way
4544
		if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
4545
			this.currentItem.hide();
4546
		}
4547
4548
		//Create the placeholder
4549
		this._createPlaceholder();
4550
4551
		//Set a containment if given in the options
4552
		if ( o.containment ) {
4553
			this._setContainment();
4554
		}
4555
4556
		if ( o.cursor && o.cursor !== "auto" ) { // cursor option
4557
			body = this.document.find( "body" );
4558
4559
			// Support: IE
4560
			this.storedCursor = body.css( "cursor" );
4561
			body.css( "cursor", o.cursor );
4562
4563
			this.storedStylesheet =
4564
				$( "<style>*{ cursor: " + o.cursor + " !important; }</style>" ).appendTo( body );
4565
		}
4566
4567
		if ( o.opacity ) { // opacity option
4568
			if ( this.helper.css( "opacity" ) ) {
4569
				this._storedOpacity = this.helper.css( "opacity" );
4570
			}
4571
			this.helper.css( "opacity", o.opacity );
4572
		}
4573
4574
		if ( o.zIndex ) { // zIndex option
4575
			if ( this.helper.css( "zIndex" ) ) {
4576
				this._storedZIndex = this.helper.css( "zIndex" );
4577
			}
4578
			this.helper.css( "zIndex", o.zIndex );
4579
		}
4580
4581
		//Prepare scrolling
4582
		if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
4583
				this.scrollParent[ 0 ].tagName !== "HTML" ) {
4584
			this.overflowOffset = this.scrollParent.offset();
4585
		}
4586
4587
		//Call callbacks
4588
		this._trigger( "start", event, this._uiHash() );
4589
4590
		//Recache the helper size
4591
		if ( !this._preserveHelperProportions ) {
4592
			this._cacheHelperProportions();
4593
		}
4594
4595
		//Post "activate" events to possible containers
4596
		if ( !noActivation ) {
4597
			for ( i = this.containers.length - 1; i >= 0; i-- ) {
4598
				this.containers[ i ]._trigger( "activate", event, this._uiHash( this ) );
4599
			}
4600
		}
4601
4602
		//Prepare possible droppables
4603
		if ( $.ui.ddmanager ) {
4604
			$.ui.ddmanager.current = this;
4605
		}
4606
4607
		if ( $.ui.ddmanager && !o.dropBehaviour ) {
4608
			$.ui.ddmanager.prepareOffsets( this, event );
4609
		}
4610
4611
		this.dragging = true;
4612
4613
		this._addClass( this.helper, "ui-sortable-helper" );
4614
4615
		// Execute the drag once - this causes the helper not to be visiblebefore getting its
4616
		// correct position
4617
		this._mouseDrag( event );
4618
		return true;
4619
4620
	},
4621
4622
	_mouseDrag: function( event ) {
4623
		var i, item, itemElement, intersection,
4624
			o = this.options,
4625
			scrolled = false;
4626
4627
		//Compute the helpers position
4628
		this.position = this._generatePosition( event );
4629
		this.positionAbs = this._convertPositionTo( "absolute" );
4630
4631
		if ( !this.lastPositionAbs ) {
4632
			this.lastPositionAbs = this.positionAbs;
4633
		}
4634
4635
		//Do scrolling
4636
		if ( this.options.scroll ) {
4637
			if ( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
4638
					this.scrollParent[ 0 ].tagName !== "HTML" ) {
4639
4640
				if ( ( this.overflowOffset.top + this.scrollParent[ 0 ].offsetHeight ) -
4641
						event.pageY < o.scrollSensitivity ) {
4642
					this.scrollParent[ 0 ].scrollTop =
4643
						scrolled = this.scrollParent[ 0 ].scrollTop + o.scrollSpeed;
4644
				} else if ( event.pageY - this.overflowOffset.top < o.scrollSensitivity ) {
4645
					this.scrollParent[ 0 ].scrollTop =
4646
						scrolled = this.scrollParent[ 0 ].scrollTop - o.scrollSpeed;
4647
				}
4648
4649
				if ( ( this.overflowOffset.left + this.scrollParent[ 0 ].offsetWidth ) -
4650
						event.pageX < o.scrollSensitivity ) {
4651
					this.scrollParent[ 0 ].scrollLeft = scrolled =
4652
						this.scrollParent[ 0 ].scrollLeft + o.scrollSpeed;
4653
				} else if ( event.pageX - this.overflowOffset.left < o.scrollSensitivity ) {
4654
					this.scrollParent[ 0 ].scrollLeft = scrolled =
4655
						this.scrollParent[ 0 ].scrollLeft - o.scrollSpeed;
4656
				}
4657
4658
			} else {
4659
4660
				if ( event.pageY - this.document.scrollTop() < o.scrollSensitivity ) {
4661
					scrolled = this.document.scrollTop( this.document.scrollTop() - o.scrollSpeed );
4662
				} else if ( this.window.height() - ( event.pageY - this.document.scrollTop() ) <
4663
						o.scrollSensitivity ) {
4664
					scrolled = this.document.scrollTop( this.document.scrollTop() + o.scrollSpeed );
4665
				}
4666
4667
				if ( event.pageX - this.document.scrollLeft() < o.scrollSensitivity ) {
4668
					scrolled = this.document.scrollLeft(
4669
						this.document.scrollLeft() - o.scrollSpeed
4670
					);
4671
				} else if ( this.window.width() - ( event.pageX - this.document.scrollLeft() ) <
4672
						o.scrollSensitivity ) {
4673
					scrolled = this.document.scrollLeft(
4674
						this.document.scrollLeft() + o.scrollSpeed
4675
					);
4676
				}
4677
4678
			}
4679
4680
			if ( scrolled !== false && $.ui.ddmanager && !o.dropBehaviour ) {
4681
				$.ui.ddmanager.prepareOffsets( this, event );
4682
			}
4683
		}
4684
4685
		//Regenerate the absolute position used for position checks
4686
		this.positionAbs = this._convertPositionTo( "absolute" );
4687
4688
		//Set the helper position
4689
		if ( !this.options.axis || this.options.axis !== "y" ) {
4690
			this.helper[ 0 ].style.left = this.position.left + "px";
4691
		}
4692
		if ( !this.options.axis || this.options.axis !== "x" ) {
4693
			this.helper[ 0 ].style.top = this.position.top + "px";
4694
		}
4695
4696
		//Rearrange
4697
		for ( i = this.items.length - 1; i >= 0; i-- ) {
4698
4699
			//Cache variables and intersection, continue if no intersection
4700
			item = this.items[ i ];
4701
			itemElement = item.item[ 0 ];
4702
			intersection = this._intersectsWithPointer( item );
4703
			if ( !intersection ) {
4704
				continue;
4705
			}
4706
4707
			// Only put the placeholder inside the current Container, skip all
4708
			// items from other containers. This works because when moving
4709
			// an item from one container to another the
4710
			// currentContainer is switched before the placeholder is moved.
4711
			//
4712
			// Without this, moving items in "sub-sortables" can cause
4713
			// the placeholder to jitter between the outer and inner container.
4714
			if ( item.instance !== this.currentContainer ) {
4715
				continue;
4716
			}
4717
4718
			// Cannot intersect with itself
4719
			// no useless actions that have been done before
4720
			// no action if the item moved is the parent of the item checked
4721
			if ( itemElement !== this.currentItem[ 0 ] &&
4722
				this.placeholder[ intersection === 1 ? "next" : "prev" ]()[ 0 ] !== itemElement &&
4723
				!$.contains( this.placeholder[ 0 ], itemElement ) &&
4724
				( this.options.type === "semi-dynamic" ?
4725
					!$.contains( this.element[ 0 ], itemElement ) :
4726
					true
4727
				)
4728
			) {
4729
4730
				this.direction = intersection === 1 ? "down" : "up";
4731
4732
				if ( this.options.tolerance === "pointer" || this._intersectsWithSides( item ) ) {
4733
					this._rearrange( event, item );
4734
				} else {
4735
					break;
4736
				}
4737
4738
				this._trigger( "change", event, this._uiHash() );
4739
				break;
4740
			}
4741
		}
4742
4743
		//Post events to containers
4744
		this._contactContainers( event );
4745
4746
		//Interconnect with droppables
4747
		if ( $.ui.ddmanager ) {
4748
			$.ui.ddmanager.drag( this, event );
4749
		}
4750
4751
		//Call callbacks
4752
		this._trigger( "sort", event, this._uiHash() );
4753
4754
		this.lastPositionAbs = this.positionAbs;
4755
		return false;
4756
4757
	},
4758
4759
	_mouseStop: function( event, noPropagation ) {
4760
4761
		if ( !event ) {
4762
			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...
4763
		}
4764
4765
		//If we are using droppables, inform the manager about the drop
4766
		if ( $.ui.ddmanager && !this.options.dropBehaviour ) {
4767
			$.ui.ddmanager.drop( this, event );
4768
		}
4769
4770
		if ( this.options.revert ) {
4771
			var that = this,
4772
				cur = this.placeholder.offset(),
4773
				axis = this.options.axis,
4774
				animation = {};
4775
4776
			if ( !axis || axis === "x" ) {
4777
				animation.left = cur.left - this.offset.parent.left - this.margins.left +
4778
					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
4779
						0 :
4780
						this.offsetParent[ 0 ].scrollLeft
4781
					);
4782
			}
4783
			if ( !axis || axis === "y" ) {
4784
				animation.top = cur.top - this.offset.parent.top - this.margins.top +
4785
					( this.offsetParent[ 0 ] === this.document[ 0 ].body ?
4786
						0 :
4787
						this.offsetParent[ 0 ].scrollTop
4788
					);
4789
			}
4790
			this.reverting = true;
4791
			$( this.helper ).animate(
4792
				animation,
4793
				parseInt( this.options.revert, 10 ) || 500,
4794
				function() {
4795
					that._clear( event );
4796
				}
4797
			);
4798
		} else {
4799
			this._clear( event, noPropagation );
4800
		}
4801
4802
		return false;
4803
4804
	},
4805
4806
	cancel: function() {
4807
4808
		if ( this.dragging ) {
4809
4810
			this._mouseUp( { target: null } );
4811
4812
			if ( this.options.helper === "original" ) {
4813
				this.currentItem.css( this._storedCSS );
4814
				this._removeClass( this.currentItem, "ui-sortable-helper" );
4815
			} else {
4816
				this.currentItem.show();
4817
			}
4818
4819
			//Post deactivating events to containers
4820
			for ( var i = this.containers.length - 1; i >= 0; i-- ) {
4821
				this.containers[ i ]._trigger( "deactivate", null, this._uiHash( this ) );
4822
				if ( this.containers[ i ].containerCache.over ) {
4823
					this.containers[ i ]._trigger( "out", null, this._uiHash( this ) );
4824
					this.containers[ i ].containerCache.over = 0;
4825
				}
4826
			}
4827
4828
		}
4829
4830
		if ( this.placeholder ) {
4831
4832
			//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
4833
			// it unbinds ALL events from the original node!
4834
			if ( this.placeholder[ 0 ].parentNode ) {
4835
				this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
4836
			}
4837
			if ( this.options.helper !== "original" && this.helper &&
4838
					this.helper[ 0 ].parentNode ) {
4839
				this.helper.remove();
4840
			}
4841
4842
			$.extend( this, {
4843
				helper: null,
4844
				dragging: false,
4845
				reverting: false,
4846
				_noFinalSort: null
4847
			} );
4848
4849
			if ( this.domPosition.prev ) {
4850
				$( this.domPosition.prev ).after( this.currentItem );
4851
			} else {
4852
				$( this.domPosition.parent ).prepend( this.currentItem );
4853
			}
4854
		}
4855
4856
		return this;
4857
4858
	},
4859
4860
	serialize: function( o ) {
4861
4862
		var items = this._getItemsAsjQuery( o && o.connected ),
4863
			str = [];
4864
		o = o || {};
4865
4866
		$( items ).each( function() {
4867
			var res = ( $( o.item || this ).attr( o.attribute || "id" ) || "" )
4868
				.match( o.expression || ( /(.+)[\-=_](.+)/ ) );
4869
			if ( res ) {
4870
				str.push(
4871
					( o.key || res[ 1 ] + "[]" ) +
4872
					"=" + ( o.key && o.expression ? res[ 1 ] : res[ 2 ] ) );
4873
			}
4874
		} );
4875
4876
		if ( !str.length && o.key ) {
4877
			str.push( o.key + "=" );
4878
		}
4879
4880
		return str.join( "&" );
4881
4882
	},
4883
4884
	toArray: function( o ) {
4885
4886
		var items = this._getItemsAsjQuery( o && o.connected ),
4887
			ret = [];
4888
4889
		o = o || {};
4890
4891
		items.each( function() {
4892
			ret.push( $( o.item || this ).attr( o.attribute || "id" ) || "" );
4893
		} );
4894
		return ret;
4895
4896
	},
4897
4898
	/* Be careful with the following core functions */
4899
	_intersectsWith: function( item ) {
4900
4901
		var x1 = this.positionAbs.left,
4902
			x2 = x1 + this.helperProportions.width,
4903
			y1 = this.positionAbs.top,
4904
			y2 = y1 + this.helperProportions.height,
4905
			l = item.left,
4906
			r = l + item.width,
4907
			t = item.top,
4908
			b = t + item.height,
4909
			dyClick = this.offset.click.top,
4910
			dxClick = this.offset.click.left,
4911
			isOverElementHeight = ( this.options.axis === "x" ) || ( ( y1 + dyClick ) > t &&
4912
				( y1 + dyClick ) < b ),
4913
			isOverElementWidth = ( this.options.axis === "y" ) || ( ( x1 + dxClick ) > l &&
4914
				( x1 + dxClick ) < r ),
4915
			isOverElement = isOverElementHeight && isOverElementWidth;
4916
4917
		if ( this.options.tolerance === "pointer" ||
4918
			this.options.forcePointerForContainers ||
4919
			( this.options.tolerance !== "pointer" &&
4920
				this.helperProportions[ this.floating ? "width" : "height" ] >
4921
				item[ this.floating ? "width" : "height" ] )
4922
		) {
4923
			return isOverElement;
4924
		} 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...
4925
4926
			return ( l < x1 + ( this.helperProportions.width / 2 ) && // Right Half
4927
				x2 - ( this.helperProportions.width / 2 ) < r && // Left Half
4928
				t < y1 + ( this.helperProportions.height / 2 ) && // Bottom Half
4929
				y2 - ( this.helperProportions.height / 2 ) < b ); // Top Half
4930
4931
		}
4932
	},
4933
4934
	_intersectsWithPointer: function( item ) {
4935
		var verticalDirection, horizontalDirection,
4936
			isOverElementHeight = ( this.options.axis === "x" ) ||
4937
				this._isOverAxis(
4938
					this.positionAbs.top + this.offset.click.top, item.top, item.height ),
4939
			isOverElementWidth = ( this.options.axis === "y" ) ||
4940
				this._isOverAxis(
4941
					this.positionAbs.left + this.offset.click.left, item.left, item.width ),
4942
			isOverElement = isOverElementHeight && isOverElementWidth;
4943
4944
		if ( !isOverElement ) {
4945
			return false;
4946
		}
4947
4948
		verticalDirection = this._getDragVerticalDirection();
4949
		horizontalDirection = this._getDragHorizontalDirection();
4950
4951
		return this.floating ?
4952
			( ( horizontalDirection === "right" || verticalDirection === "down" ) ? 2 : 1 )
4953
			: ( verticalDirection && ( verticalDirection === "down" ? 2 : 1 ) );
4954
4955
	},
4956
4957
	_intersectsWithSides: function( item ) {
4958
4959
		var isOverBottomHalf = this._isOverAxis( this.positionAbs.top +
4960
				this.offset.click.top, item.top + ( item.height / 2 ), item.height ),
4961
			isOverRightHalf = this._isOverAxis( this.positionAbs.left +
4962
				this.offset.click.left, item.left + ( item.width / 2 ), item.width ),
4963
			verticalDirection = this._getDragVerticalDirection(),
4964
			horizontalDirection = this._getDragHorizontalDirection();
4965
4966
		if ( this.floating && horizontalDirection ) {
4967
			return ( ( horizontalDirection === "right" && isOverRightHalf ) ||
4968
				( horizontalDirection === "left" && !isOverRightHalf ) );
4969
		} 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...
4970
			return verticalDirection && ( ( verticalDirection === "down" && isOverBottomHalf ) ||
4971
				( verticalDirection === "up" && !isOverBottomHalf ) );
4972
		}
4973
4974
	},
4975
4976
	_getDragVerticalDirection: function() {
4977
		var delta = this.positionAbs.top - this.lastPositionAbs.top;
4978
		return delta !== 0 && ( delta > 0 ? "down" : "up" );
4979
	},
4980
4981
	_getDragHorizontalDirection: function() {
4982
		var delta = this.positionAbs.left - this.lastPositionAbs.left;
4983
		return delta !== 0 && ( delta > 0 ? "right" : "left" );
4984
	},
4985
4986
	refresh: function( event ) {
4987
		this._refreshItems( event );
4988
		this._setHandleClassName();
4989
		this.refreshPositions();
4990
		return this;
4991
	},
4992
4993
	_connectWith: function() {
4994
		var options = this.options;
4995
		return options.connectWith.constructor === String ?
4996
			[ options.connectWith ] :
4997
			options.connectWith;
4998
	},
4999
5000
	_getItemsAsjQuery: function( connected ) {
5001
5002
		var i, j, cur, inst,
5003
			items = [],
5004
			queries = [],
5005
			connectWith = this._connectWith();
5006
5007
		if ( connectWith && connected ) {
5008
			for ( i = connectWith.length - 1; i >= 0; i-- ) {
5009
				cur = $( connectWith[ i ], this.document[ 0 ] );
5010
				for ( j = cur.length - 1; j >= 0; j-- ) {
5011
					inst = $.data( cur[ j ], this.widgetFullName );
5012
					if ( inst && inst !== this && !inst.options.disabled ) {
5013
						queries.push( [ $.isFunction( inst.options.items ) ?
5014
							inst.options.items.call( inst.element ) :
5015
							$( inst.options.items, inst.element )
5016
								.not( ".ui-sortable-helper" )
5017
								.not( ".ui-sortable-placeholder" ), inst ] );
5018
					}
5019
				}
5020
			}
5021
		}
5022
5023
		queries.push( [ $.isFunction( this.options.items ) ?
5024
			this.options.items
5025
				.call( this.element, null, { options: this.options, item: this.currentItem } ) :
5026
			$( this.options.items, this.element )
5027
				.not( ".ui-sortable-helper" )
5028
				.not( ".ui-sortable-placeholder" ), this ] );
5029
5030
		function addItems() {
5031
			items.push( this );
5032
		}
5033
		for ( i = queries.length - 1; i >= 0; i-- ) {
5034
			queries[ i ][ 0 ].each( addItems );
5035
		}
5036
5037
		return $( items );
5038
5039
	},
5040
5041
	_removeCurrentsFromItems: function() {
5042
5043
		var list = this.currentItem.find( ":data(" + this.widgetName + "-item)" );
5044
5045
		this.items = $.grep( this.items, function( item ) {
5046
			for ( var j = 0; j < list.length; j++ ) {
5047
				if ( list[ j ] === item.item[ 0 ] ) {
5048
					return false;
5049
				}
5050
			}
5051
			return true;
5052
		} );
5053
5054
	},
5055
5056
	_refreshItems: function( event ) {
5057
5058
		this.items = [];
5059
		this.containers = [ this ];
5060
5061
		var i, j, cur, inst, targetData, _queries, item, queriesLength,
5062
			items = this.items,
5063
			queries = [ [ $.isFunction( this.options.items ) ?
5064
				this.options.items.call( this.element[ 0 ], event, { item: this.currentItem } ) :
5065
				$( this.options.items, this.element ), this ] ],
5066
			connectWith = this._connectWith();
5067
5068
		//Shouldn't be run the first time through due to massive slow-down
5069
		if ( connectWith && this.ready ) {
5070
			for ( i = connectWith.length - 1; i >= 0; i-- ) {
5071
				cur = $( connectWith[ i ], this.document[ 0 ] );
5072
				for ( j = cur.length - 1; j >= 0; j-- ) {
5073
					inst = $.data( cur[ j ], this.widgetFullName );
5074
					if ( inst && inst !== this && !inst.options.disabled ) {
5075
						queries.push( [ $.isFunction( inst.options.items ) ?
5076
							inst.options.items
5077
								.call( inst.element[ 0 ], event, { item: this.currentItem } ) :
5078
							$( inst.options.items, inst.element ), inst ] );
5079
						this.containers.push( inst );
5080
					}
5081
				}
5082
			}
5083
		}
5084
5085
		for ( i = queries.length - 1; i >= 0; i-- ) {
5086
			targetData = queries[ i ][ 1 ];
5087
			_queries = queries[ i ][ 0 ];
5088
5089
			for ( j = 0, queriesLength = _queries.length; j < queriesLength; j++ ) {
5090
				item = $( _queries[ j ] );
5091
5092
				// Data for target checking (mouse manager)
5093
				item.data( this.widgetName + "-item", targetData );
5094
5095
				items.push( {
5096
					item: item,
5097
					instance: targetData,
5098
					width: 0, height: 0,
5099
					left: 0, top: 0
5100
				} );
5101
			}
5102
		}
5103
5104
	},
5105
5106
	refreshPositions: function( fast ) {
5107
5108
		// Determine whether items are being displayed horizontally
5109
		this.floating = this.items.length ?
5110
			this.options.axis === "x" || this._isFloating( this.items[ 0 ].item ) :
5111
			false;
5112
5113
		//This has to be redone because due to the item being moved out/into the offsetParent,
5114
		// the offsetParent's position will change
5115
		if ( this.offsetParent && this.helper ) {
5116
			this.offset.parent = this._getParentOffset();
5117
		}
5118
5119
		var i, item, t, p;
5120
5121
		for ( i = this.items.length - 1; i >= 0; i-- ) {
5122
			item = this.items[ i ];
5123
5124
			//We ignore calculating positions of all connected containers when we're not over them
5125
			if ( item.instance !== this.currentContainer && this.currentContainer &&
5126
					item.item[ 0 ] !== this.currentItem[ 0 ] ) {
5127
				continue;
5128
			}
5129
5130
			t = this.options.toleranceElement ?
5131
				$( this.options.toleranceElement, item.item ) :
5132
				item.item;
5133
5134
			if ( !fast ) {
5135
				item.width = t.outerWidth();
5136
				item.height = t.outerHeight();
5137
			}
5138
5139
			p = t.offset();
5140
			item.left = p.left;
5141
			item.top = p.top;
5142
		}
5143
5144
		if ( this.options.custom && this.options.custom.refreshContainers ) {
5145
			this.options.custom.refreshContainers.call( this );
5146
		} else {
5147
			for ( i = this.containers.length - 1; i >= 0; i-- ) {
5148
				p = this.containers[ i ].element.offset();
5149
				this.containers[ i ].containerCache.left = p.left;
5150
				this.containers[ i ].containerCache.top = p.top;
5151
				this.containers[ i ].containerCache.width =
5152
					this.containers[ i ].element.outerWidth();
5153
				this.containers[ i ].containerCache.height =
5154
					this.containers[ i ].element.outerHeight();
5155
			}
5156
		}
5157
5158
		return this;
5159
	},
5160
5161
	_createPlaceholder: function( that ) {
5162
		that = that || this;
5163
		var className,
5164
			o = that.options;
5165
5166
		if ( !o.placeholder || o.placeholder.constructor === String ) {
5167
			className = o.placeholder;
5168
			o.placeholder = {
5169
				element: function() {
5170
5171
					var nodeName = that.currentItem[ 0 ].nodeName.toLowerCase(),
5172
						element = $( "<" + nodeName + ">", that.document[ 0 ] );
5173
5174
						that._addClass( element, "ui-sortable-placeholder",
5175
								className || that.currentItem[ 0 ].className )
5176
							._removeClass( element, "ui-sortable-helper" );
5177
5178
					if ( nodeName === "tbody" ) {
5179
						that._createTrPlaceholder(
5180
							that.currentItem.find( "tr" ).eq( 0 ),
5181
							$( "<tr>", that.document[ 0 ] ).appendTo( element )
5182
						);
5183
					} else if ( nodeName === "tr" ) {
5184
						that._createTrPlaceholder( that.currentItem, element );
5185
					} else if ( nodeName === "img" ) {
5186
						element.attr( "src", that.currentItem.attr( "src" ) );
5187
					}
5188
5189
					if ( !className ) {
5190
						element.css( "visibility", "hidden" );
5191
					}
5192
5193
					return element;
5194
				},
5195
				update: function( container, p ) {
5196
5197
					// 1. If a className is set as 'placeholder option, we don't force sizes -
5198
					// the class is responsible for that
5199
					// 2. The option 'forcePlaceholderSize can be enabled to force it even if a
5200
					// class name is specified
5201
					if ( className && !o.forcePlaceholderSize ) {
5202
						return;
5203
					}
5204
5205
					//If the element doesn't have a actual height by itself (without styles coming
5206
					// from a stylesheet), it receives the inline height from the dragged item
5207
					if ( !p.height() ) {
5208
						p.height(
5209
							that.currentItem.innerHeight() -
5210
							parseInt( that.currentItem.css( "paddingTop" ) || 0, 10 ) -
5211
							parseInt( that.currentItem.css( "paddingBottom" ) || 0, 10 ) );
5212
					}
5213
					if ( !p.width() ) {
5214
						p.width(
5215
							that.currentItem.innerWidth() -
5216
							parseInt( that.currentItem.css( "paddingLeft" ) || 0, 10 ) -
5217
							parseInt( that.currentItem.css( "paddingRight" ) || 0, 10 ) );
5218
					}
5219
				}
5220
			};
5221
		}
5222
5223
		//Create the placeholder
5224
		that.placeholder = $( o.placeholder.element.call( that.element, that.currentItem ) );
5225
5226
		//Append it after the actual current item
5227
		that.currentItem.after( that.placeholder );
5228
5229
		//Update the size of the placeholder (TODO: Logic to fuzzy, see line 316/317)
5230
		o.placeholder.update( that, that.placeholder );
5231
5232
	},
5233
5234
	_createTrPlaceholder: function( sourceTr, targetTr ) {
5235
		var that = this;
5236
5237
		sourceTr.children().each( function() {
5238
			$( "<td>&#160;</td>", that.document[ 0 ] )
5239
				.attr( "colspan", $( this ).attr( "colspan" ) || 1 )
5240
				.appendTo( targetTr );
5241
		} );
5242
	},
5243
5244
	_contactContainers: function( event ) {
5245
		var i, j, dist, itemWithLeastDistance, posProperty, sizeProperty, cur, nearBottom,
5246
			floating, axis,
5247
			innermostContainer = null,
5248
			innermostIndex = null;
5249
5250
		// Get innermost container that intersects with item
5251
		for ( i = this.containers.length - 1; i >= 0; i-- ) {
5252
5253
			// Never consider a container that's located within the item itself
5254
			if ( $.contains( this.currentItem[ 0 ], this.containers[ i ].element[ 0 ] ) ) {
5255
				continue;
5256
			}
5257
5258
			if ( this._intersectsWith( this.containers[ i ].containerCache ) ) {
5259
5260
				// If we've already found a container and it's more "inner" than this, then continue
5261
				if ( innermostContainer &&
5262
						$.contains(
5263
							this.containers[ i ].element[ 0 ],
5264
							innermostContainer.element[ 0 ] ) ) {
5265
					continue;
5266
				}
5267
5268
				innermostContainer = this.containers[ i ];
5269
				innermostIndex = i;
5270
5271
			} else {
5272
5273
				// container doesn't intersect. trigger "out" event if necessary
5274
				if ( this.containers[ i ].containerCache.over ) {
5275
					this.containers[ i ]._trigger( "out", event, this._uiHash( this ) );
5276
					this.containers[ i ].containerCache.over = 0;
5277
				}
5278
			}
5279
5280
		}
5281
5282
		// If no intersecting containers found, return
5283
		if ( !innermostContainer ) {
5284
			return;
5285
		}
5286
5287
		// Move the item into the container if it's not there already
5288
		if ( this.containers.length === 1 ) {
5289
			if ( !this.containers[ innermostIndex ].containerCache.over ) {
5290
				this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
5291
				this.containers[ innermostIndex ].containerCache.over = 1;
5292
			}
5293
		} else {
5294
5295
			// When entering a new container, we will find the item with the least distance and
5296
			// append our item near it
5297
			dist = 10000;
5298
			itemWithLeastDistance = null;
5299
			floating = innermostContainer.floating || this._isFloating( this.currentItem );
5300
			posProperty = floating ? "left" : "top";
5301
			sizeProperty = floating ? "width" : "height";
5302
			axis = floating ? "pageX" : "pageY";
5303
5304
			for ( j = this.items.length - 1; j >= 0; j-- ) {
5305
				if ( !$.contains(
5306
						this.containers[ innermostIndex ].element[ 0 ], this.items[ j ].item[ 0 ] )
5307
				) {
5308
					continue;
5309
				}
5310
				if ( this.items[ j ].item[ 0 ] === this.currentItem[ 0 ] ) {
5311
					continue;
5312
				}
5313
5314
				cur = this.items[ j ].item.offset()[ posProperty ];
5315
				nearBottom = false;
5316
				if ( event[ axis ] - cur > this.items[ j ][ sizeProperty ] / 2 ) {
5317
					nearBottom = true;
5318
				}
5319
5320
				if ( Math.abs( event[ axis ] - cur ) < dist ) {
5321
					dist = Math.abs( event[ axis ] - cur );
5322
					itemWithLeastDistance = this.items[ j ];
5323
					this.direction = nearBottom ? "up" : "down";
5324
				}
5325
			}
5326
5327
			//Check if dropOnEmpty is enabled
5328
			if ( !itemWithLeastDistance && !this.options.dropOnEmpty ) {
5329
				return;
5330
			}
5331
5332
			if ( this.currentContainer === this.containers[ innermostIndex ] ) {
5333
				if ( !this.currentContainer.containerCache.over ) {
5334
					this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash() );
5335
					this.currentContainer.containerCache.over = 1;
5336
				}
5337
				return;
5338
			}
5339
5340
			itemWithLeastDistance ?
5341
				this._rearrange( event, itemWithLeastDistance, null, true ) :
5342
				this._rearrange( event, null, this.containers[ innermostIndex ].element, true );
5343
			this._trigger( "change", event, this._uiHash() );
5344
			this.containers[ innermostIndex ]._trigger( "change", event, this._uiHash( this ) );
5345
			this.currentContainer = this.containers[ innermostIndex ];
5346
5347
			//Update the placeholder
5348
			this.options.placeholder.update( this.currentContainer, this.placeholder );
5349
5350
			this.containers[ innermostIndex ]._trigger( "over", event, this._uiHash( this ) );
5351
			this.containers[ innermostIndex ].containerCache.over = 1;
5352
		}
5353
5354
	},
5355
5356
	_createHelper: function( event ) {
5357
5358
		var o = this.options,
5359
			helper = $.isFunction( o.helper ) ?
5360
				$( o.helper.apply( this.element[ 0 ], [ event, this.currentItem ] ) ) :
5361
				( o.helper === "clone" ? this.currentItem.clone() : this.currentItem );
5362
5363
		//Add the helper to the DOM if that didn't happen already
5364
		if ( !helper.parents( "body" ).length ) {
5365
			$( o.appendTo !== "parent" ?
5366
				o.appendTo :
5367
				this.currentItem[ 0 ].parentNode )[ 0 ].appendChild( helper[ 0 ] );
5368
		}
5369
5370
		if ( helper[ 0 ] === this.currentItem[ 0 ] ) {
5371
			this._storedCSS = {
5372
				width: this.currentItem[ 0 ].style.width,
5373
				height: this.currentItem[ 0 ].style.height,
5374
				position: this.currentItem.css( "position" ),
5375
				top: this.currentItem.css( "top" ),
5376
				left: this.currentItem.css( "left" )
5377
			};
5378
		}
5379
5380
		if ( !helper[ 0 ].style.width || o.forceHelperSize ) {
5381
			helper.width( this.currentItem.width() );
5382
		}
5383
		if ( !helper[ 0 ].style.height || o.forceHelperSize ) {
5384
			helper.height( this.currentItem.height() );
5385
		}
5386
5387
		return helper;
5388
5389
	},
5390
5391 View Code Duplication
	_adjustOffsetFromHelper: function( obj ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5392
		if ( typeof obj === "string" ) {
5393
			obj = obj.split( " " );
5394
		}
5395
		if ( $.isArray( obj ) ) {
5396
			obj = { left: +obj[ 0 ], top: +obj[ 1 ] || 0 };
5397
		}
5398
		if ( "left" in obj ) {
5399
			this.offset.click.left = obj.left + this.margins.left;
5400
		}
5401
		if ( "right" in obj ) {
5402
			this.offset.click.left = this.helperProportions.width - obj.right + this.margins.left;
5403
		}
5404
		if ( "top" in obj ) {
5405
			this.offset.click.top = obj.top + this.margins.top;
5406
		}
5407
		if ( "bottom" in obj ) {
5408
			this.offset.click.top = this.helperProportions.height - obj.bottom + this.margins.top;
5409
		}
5410
	},
5411
5412
	_getParentOffset: function() {
5413
5414
		//Get the offsetParent and cache its position
5415
		this.offsetParent = this.helper.offsetParent();
5416
		var po = this.offsetParent.offset();
5417
5418
		// This is a special case where we need to modify a offset calculated on start, since the
5419
		// following happened:
5420
		// 1. The position of the helper is absolute, so it's position is calculated based on the
5421
		// next positioned parent
5422
		// 2. The actual offset parent is a child of the scroll parent, and the scroll parent isn't
5423
		// the document, which means that the scroll is included in the initial calculation of the
5424
		// offset of the parent, and never recalculated upon drag
5425
		if ( this.cssPosition === "absolute" && this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5426
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) {
5427
			po.left += this.scrollParent.scrollLeft();
5428
			po.top += this.scrollParent.scrollTop();
5429
		}
5430
5431
		// This needs to be actually done for all browsers, since pageX/pageY includes this
5432
		// information with an ugly IE fix
5433
		if ( this.offsetParent[ 0 ] === this.document[ 0 ].body ||
5434
				( this.offsetParent[ 0 ].tagName &&
5435
				this.offsetParent[ 0 ].tagName.toLowerCase() === "html" && $.ui.ie ) ) {
5436
			po = { top: 0, left: 0 };
5437
		}
5438
5439
		return {
5440
			top: po.top + ( parseInt( this.offsetParent.css( "borderTopWidth" ), 10 ) || 0 ),
5441
			left: po.left + ( parseInt( this.offsetParent.css( "borderLeftWidth" ), 10 ) || 0 )
5442
		};
5443
5444
	},
5445
5446
	_getRelativeOffset: function() {
5447
5448
		if ( this.cssPosition === "relative" ) {
5449
			var p = this.currentItem.position();
5450
			return {
5451
				top: p.top - ( parseInt( this.helper.css( "top" ), 10 ) || 0 ) +
5452
					this.scrollParent.scrollTop(),
5453
				left: p.left - ( parseInt( this.helper.css( "left" ), 10 ) || 0 ) +
5454
					this.scrollParent.scrollLeft()
5455
			};
5456
		} 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...
5457
			return { top: 0, left: 0 };
5458
		}
5459
5460
	},
5461
5462
	_cacheMargins: function() {
5463
		this.margins = {
5464
			left: ( parseInt( this.currentItem.css( "marginLeft" ), 10 ) || 0 ),
5465
			top: ( parseInt( this.currentItem.css( "marginTop" ), 10 ) || 0 )
5466
		};
5467
	},
5468
5469
	_cacheHelperProportions: function() {
5470
		this.helperProportions = {
5471
			width: this.helper.outerWidth(),
5472
			height: this.helper.outerHeight()
5473
		};
5474
	},
5475
5476
	_setContainment: function() {
5477
5478
		var ce, co, over,
5479
			o = this.options;
5480
		if ( o.containment === "parent" ) {
5481
			o.containment = this.helper[ 0 ].parentNode;
5482
		}
5483
		if ( o.containment === "document" || o.containment === "window" ) {
5484
			this.containment = [
5485
				0 - this.offset.relative.left - this.offset.parent.left,
5486
				0 - this.offset.relative.top - this.offset.parent.top,
5487
				o.containment === "document" ?
5488
					this.document.width() :
5489
					this.window.width() - this.helperProportions.width - this.margins.left,
5490
				( o.containment === "document" ?
5491
					( this.document.height() || document.body.parentNode.scrollHeight ) :
5492
					this.window.height() || this.document[ 0 ].body.parentNode.scrollHeight
5493
				) - this.helperProportions.height - this.margins.top
5494
			];
5495
		}
5496
5497
		if ( !( /^(document|window|parent)$/ ).test( o.containment ) ) {
5498
			ce = $( o.containment )[ 0 ];
5499
			co = $( o.containment ).offset();
5500
			over = ( $( ce ).css( "overflow" ) !== "hidden" );
5501
5502
			this.containment = [
5503
				co.left + ( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) +
5504
					( parseInt( $( ce ).css( "paddingLeft" ), 10 ) || 0 ) - this.margins.left,
5505
				co.top + ( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) +
5506
					( parseInt( $( ce ).css( "paddingTop" ), 10 ) || 0 ) - this.margins.top,
5507
				co.left + ( over ? Math.max( ce.scrollWidth, ce.offsetWidth ) : ce.offsetWidth ) -
5508
					( parseInt( $( ce ).css( "borderLeftWidth" ), 10 ) || 0 ) -
5509
					( parseInt( $( ce ).css( "paddingRight" ), 10 ) || 0 ) -
5510
					this.helperProportions.width - this.margins.left,
5511
				co.top + ( over ? Math.max( ce.scrollHeight, ce.offsetHeight ) : ce.offsetHeight ) -
5512
					( parseInt( $( ce ).css( "borderTopWidth" ), 10 ) || 0 ) -
5513
					( parseInt( $( ce ).css( "paddingBottom" ), 10 ) || 0 ) -
5514
					this.helperProportions.height - this.margins.top
5515
			];
5516
		}
5517
5518
	},
5519
5520
	_convertPositionTo: function( d, pos ) {
5521
5522
		if ( !pos ) {
5523
			pos = this.position;
5524
		}
5525
		var mod = d === "absolute" ? 1 : -1,
5526
			scroll = this.cssPosition === "absolute" &&
5527
				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5528
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
5529
					this.offsetParent :
5530
					this.scrollParent,
5531
			scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
5532
5533
		return {
5534
			top: (
5535
5536
				// The absolute mouse position
5537
				pos.top	+
5538
5539
				// Only for relative positioned nodes: Relative offset from element to offset parent
5540
				this.offset.relative.top * mod +
5541
5542
				// The offsetParent's offset without borders (offset + border)
5543
				this.offset.parent.top * mod -
5544
				( ( this.cssPosition === "fixed" ?
5545
					-this.scrollParent.scrollTop() :
5546
					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) * mod )
5547
			),
5548
			left: (
5549
5550
				// The absolute mouse position
5551
				pos.left +
5552
5553
				// Only for relative positioned nodes: Relative offset from element to offset parent
5554
				this.offset.relative.left * mod +
5555
5556
				// The offsetParent's offset without borders (offset + border)
5557
				this.offset.parent.left * mod	-
5558
				( ( this.cssPosition === "fixed" ?
5559
					-this.scrollParent.scrollLeft() : scrollIsRootNode ? 0 :
5560
					scroll.scrollLeft() ) * mod )
5561
			)
5562
		};
5563
5564
	},
5565
5566
	_generatePosition: function( event ) {
5567
5568
		var top, left,
5569
			o = this.options,
5570
			pageX = event.pageX,
5571
			pageY = event.pageY,
5572
			scroll = this.cssPosition === "absolute" &&
5573
				!( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5574
				$.contains( this.scrollParent[ 0 ], this.offsetParent[ 0 ] ) ) ?
5575
					this.offsetParent :
5576
					this.scrollParent,
5577
				scrollIsRootNode = ( /(html|body)/i ).test( scroll[ 0 ].tagName );
5578
5579
		// This is another very weird special case that only happens for relative elements:
5580
		// 1. If the css position is relative
5581
		// 2. and the scroll parent is the document or similar to the offset parent
5582
		// we have to refresh the relative offset during the scroll so there are no jumps
5583
		if ( this.cssPosition === "relative" && !( this.scrollParent[ 0 ] !== this.document[ 0 ] &&
5584
				this.scrollParent[ 0 ] !== this.offsetParent[ 0 ] ) ) {
5585
			this.offset.relative = this._getRelativeOffset();
5586
		}
5587
5588
		/*
5589
		 * - Position constraining -
5590
		 * Constrain the position to a mix of grid, containment.
5591
		 */
5592
5593
		if ( this.originalPosition ) { //If we are not dragging yet, we won't check for options
5594
5595
			if ( this.containment ) {
5596
				if ( event.pageX - this.offset.click.left < this.containment[ 0 ] ) {
5597
					pageX = this.containment[ 0 ] + this.offset.click.left;
5598
				}
5599
				if ( event.pageY - this.offset.click.top < this.containment[ 1 ] ) {
5600
					pageY = this.containment[ 1 ] + this.offset.click.top;
5601
				}
5602
				if ( event.pageX - this.offset.click.left > this.containment[ 2 ] ) {
5603
					pageX = this.containment[ 2 ] + this.offset.click.left;
5604
				}
5605
				if ( event.pageY - this.offset.click.top > this.containment[ 3 ] ) {
5606
					pageY = this.containment[ 3 ] + this.offset.click.top;
5607
				}
5608
			}
5609
5610 View Code Duplication
			if ( o.grid ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated in your project.
Loading history...
5611
				top = this.originalPageY + Math.round( ( pageY - this.originalPageY ) /
5612
					o.grid[ 1 ] ) * o.grid[ 1 ];
5613
				pageY = this.containment ?
5614
					( ( top - this.offset.click.top >= this.containment[ 1 ] &&
5615
						top - this.offset.click.top <= this.containment[ 3 ] ) ?
5616
							top :
5617
							( ( top - this.offset.click.top >= this.containment[ 1 ] ) ?
5618
								top - o.grid[ 1 ] : top + o.grid[ 1 ] ) ) :
5619
								top;
5620
5621
				left = this.originalPageX + Math.round( ( pageX - this.originalPageX ) /
5622
					o.grid[ 0 ] ) * o.grid[ 0 ];
5623
				pageX = this.containment ?
5624
					( ( left - this.offset.click.left >= this.containment[ 0 ] &&
5625
						left - this.offset.click.left <= this.containment[ 2 ] ) ?
5626
							left :
5627
							( ( left - this.offset.click.left >= this.containment[ 0 ] ) ?
5628
								left - o.grid[ 0 ] : left + o.grid[ 0 ] ) ) :
5629
								left;
5630
			}
5631
5632
		}
5633
5634
		return {
5635
			top: (
5636
5637
				// The absolute mouse position
5638
				pageY -
5639
5640
				// Click offset (relative to the element)
5641
				this.offset.click.top -
5642
5643
				// Only for relative positioned nodes: Relative offset from element to offset parent
5644
				this.offset.relative.top -
5645
5646
				// The offsetParent's offset without borders (offset + border)
5647
				this.offset.parent.top +
5648
				( ( this.cssPosition === "fixed" ?
5649
					-this.scrollParent.scrollTop() :
5650
					( scrollIsRootNode ? 0 : scroll.scrollTop() ) ) )
5651
			),
5652
			left: (
5653
5654
				// The absolute mouse position
5655
				pageX -
5656
5657
				// Click offset (relative to the element)
5658
				this.offset.click.left -
5659
5660
				// Only for relative positioned nodes: Relative offset from element to offset parent
5661
				this.offset.relative.left -
5662
5663
				// The offsetParent's offset without borders (offset + border)
5664
				this.offset.parent.left +
5665
				( ( this.cssPosition === "fixed" ?
5666
					-this.scrollParent.scrollLeft() :
5667
					scrollIsRootNode ? 0 : scroll.scrollLeft() ) )
5668
			)
5669
		};
5670
5671
	},
5672
5673
	_rearrange: function( event, i, a, hardRefresh ) {
5674
5675
		a ? a[ 0 ].appendChild( this.placeholder[ 0 ] ) :
5676
			i.item[ 0 ].parentNode.insertBefore( this.placeholder[ 0 ],
5677
				( this.direction === "down" ? i.item[ 0 ] : i.item[ 0 ].nextSibling ) );
5678
5679
		//Various things done here to improve the performance:
5680
		// 1. we create a setTimeout, that calls refreshPositions
5681
		// 2. on the instance, we have a counter variable, that get's higher after every append
5682
		// 3. on the local scope, we copy the counter variable, and check in the timeout,
5683
		// if it's still the same
5684
		// 4. this lets only the last addition to the timeout stack through
5685
		this.counter = this.counter ? ++this.counter : 1;
5686
		var counter = this.counter;
5687
5688
		this._delay( function() {
5689
			if ( counter === this.counter ) {
5690
5691
				//Precompute after each DOM insertion, NOT on mousemove
5692
				this.refreshPositions( !hardRefresh );
5693
			}
5694
		} );
5695
5696
	},
5697
5698
	_clear: function( event, noPropagation ) {
5699
5700
		this.reverting = false;
5701
5702
		// We delay all events that have to be triggered to after the point where the placeholder
5703
		// has been removed and everything else normalized again
5704
		var i,
5705
			delayedTriggers = [];
5706
5707
		// We first have to update the dom position of the actual currentItem
5708
		// Note: don't do it if the current item is already removed (by a user), or it gets
5709
		// reappended (see #4088)
5710
		if ( !this._noFinalSort && this.currentItem.parent().length ) {
5711
			this.placeholder.before( this.currentItem );
5712
		}
5713
		this._noFinalSort = null;
5714
5715
		if ( this.helper[ 0 ] === this.currentItem[ 0 ] ) {
5716
			for ( i in this._storedCSS ) {
5717
				if ( this._storedCSS[ i ] === "auto" || this._storedCSS[ i ] === "static" ) {
5718
					this._storedCSS[ i ] = "";
5719
				}
5720
			}
5721
			this.currentItem.css( this._storedCSS );
5722
			this._removeClass( this.currentItem, "ui-sortable-helper" );
5723
		} else {
5724
			this.currentItem.show();
5725
		}
5726
5727
		if ( this.fromOutside && !noPropagation ) {
5728
			delayedTriggers.push( function( event ) {
5729
				this._trigger( "receive", event, this._uiHash( this.fromOutside ) );
5730
			} );
5731
		}
5732
		if ( ( this.fromOutside ||
5733
				this.domPosition.prev !==
5734
				this.currentItem.prev().not( ".ui-sortable-helper" )[ 0 ] ||
5735
				this.domPosition.parent !== this.currentItem.parent()[ 0 ] ) && !noPropagation ) {
5736
5737
			// Trigger update callback if the DOM position has changed
5738
			delayedTriggers.push( function( event ) {
5739
				this._trigger( "update", event, this._uiHash() );
5740
			} );
5741
		}
5742
5743
		// Check if the items Container has Changed and trigger appropriate
5744
		// events.
5745
		if ( this !== this.currentContainer ) {
5746
			if ( !noPropagation ) {
5747
				delayedTriggers.push( function( event ) {
5748
					this._trigger( "remove", event, this._uiHash() );
5749
				} );
5750
				delayedTriggers.push( ( function( c ) {
5751
					return function( event ) {
5752
						c._trigger( "receive", event, this._uiHash( this ) );
5753
					};
5754
				} ).call( this, this.currentContainer ) );
5755
				delayedTriggers.push( ( function( c ) {
5756
					return function( event ) {
5757
						c._trigger( "update", event, this._uiHash( this ) );
5758
					};
5759
				} ).call( this, this.currentContainer ) );
5760
			}
5761
		}
5762
5763
		//Post events to containers
5764
		function delayEvent( type, instance, container ) {
5765
			return function( event ) {
5766
				container._trigger( type, event, instance._uiHash( instance ) );
5767
			};
5768
		}
5769
		for ( i = this.containers.length - 1; i >= 0; i-- ) {
5770
			if ( !noPropagation ) {
5771
				delayedTriggers.push( delayEvent( "deactivate", this, this.containers[ i ] ) );
5772
			}
5773
			if ( this.containers[ i ].containerCache.over ) {
5774
				delayedTriggers.push( delayEvent( "out", this, this.containers[ i ] ) );
5775
				this.containers[ i ].containerCache.over = 0;
5776
			}
5777
		}
5778
5779
		//Do what was originally in plugins
5780
		if ( this.storedCursor ) {
5781
			this.document.find( "body" ).css( "cursor", this.storedCursor );
5782
			this.storedStylesheet.remove();
5783
		}
5784
		if ( this._storedOpacity ) {
5785
			this.helper.css( "opacity", this._storedOpacity );
5786
		}
5787
		if ( this._storedZIndex ) {
5788
			this.helper.css( "zIndex", this._storedZIndex === "auto" ? "" : this._storedZIndex );
5789
		}
5790
5791
		this.dragging = false;
5792
5793
		if ( !noPropagation ) {
5794
			this._trigger( "beforeStop", event, this._uiHash() );
5795
		}
5796
5797
		//$(this.placeholder[0]).remove(); would have been the jQuery way - unfortunately,
5798
		// it unbinds ALL events from the original node!
5799
		this.placeholder[ 0 ].parentNode.removeChild( this.placeholder[ 0 ] );
5800
5801
		if ( !this.cancelHelperRemoval ) {
5802
			if ( this.helper[ 0 ] !== this.currentItem[ 0 ] ) {
5803
				this.helper.remove();
5804
			}
5805
			this.helper = null;
5806
		}
5807
5808
		if ( !noPropagation ) {
5809
			for ( i = 0; i < delayedTriggers.length; i++ ) {
5810
5811
				// Trigger all delayed events
5812
				delayedTriggers[ i ].call( this, event );
5813
			}
5814
			this._trigger( "stop", event, this._uiHash() );
5815
		}
5816
5817
		this.fromOutside = false;
5818
		return !this.cancelHelperRemoval;
5819
5820
	},
5821
5822
	_trigger: function() {
5823
		if ( $.Widget.prototype._trigger.apply( this, arguments ) === false ) {
5824
			this.cancel();
5825
		}
5826
	},
5827
5828
	_uiHash: function( _inst ) {
5829
		var inst = _inst || this;
5830
		return {
5831
			helper: inst.helper,
5832
			placeholder: inst.placeholder || $( [] ),
5833
			position: inst.position,
5834
			originalPosition: inst.originalPosition,
5835
			offset: inst.positionAbs,
5836
			item: inst.currentItem,
5837
			sender: _inst ? _inst.element : null
5838
		};
5839
	}
5840
5841
} );
5842
5843
5844
/*!
5845
 * jQuery UI Effects 1.12.0
5846
 * http://jqueryui.com
5847
 *
5848
 * Copyright jQuery Foundation and other contributors
5849
 * Released under the MIT license.
5850
 * http://jquery.org/license
5851
 */
5852
5853
//>>label: Effects Core
5854
//>>group: Effects
5855
// jscs:disable maximumLineLength
5856
//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
5857
// jscs:enable maximumLineLength
5858
//>>docs: http://api.jqueryui.com/category/effects-core/
5859
//>>demos: http://jqueryui.com/effect/
5860
5861
5862
5863
var dataSpace = "ui-effects-",
5864
	dataSpaceStyle = "ui-effects-style",
5865
	dataSpaceAnimated = "ui-effects-animated",
5866
5867
	// Create a local jQuery because jQuery Color relies on it and the
5868
	// global may not exist with AMD and a custom build (#10199)
5869
	jQuery = $;
5870
5871
$.effects = {
5872
	effect: {}
5873
};
5874
5875
/*!
5876
 * jQuery Color Animations v2.1.2
5877
 * https://github.com/jquery/jquery-color
5878
 *
5879
 * Copyright 2014 jQuery Foundation and other contributors
5880
 * Released under the MIT license.
5881
 * http://jquery.org/license
5882
 *
5883
 * Date: Wed Jan 16 08:47:09 2013 -0600
5884
 */
5885
( function( jQuery, undefined ) {
5886
5887
	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
5888
		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
5889
5890
	// Plusequals test for += 100 -= 100
5891
	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
5892
5893
	// A set of RE's that can match strings and generate color tuples.
5894
	stringParsers = [ {
5895
			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
5896
			parse: function( execResult ) {
5897
				return [
5898
					execResult[ 1 ],
5899
					execResult[ 2 ],
5900
					execResult[ 3 ],
5901
					execResult[ 4 ]
5902
				];
5903
			}
5904
		}, {
5905
			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
5906
			parse: function( execResult ) {
5907
				return [
5908
					execResult[ 1 ] * 2.55,
5909
					execResult[ 2 ] * 2.55,
5910
					execResult[ 3 ] * 2.55,
5911
					execResult[ 4 ]
5912
				];
5913
			}
5914
		}, {
5915
5916
			// This regex ignores A-F because it's compared against an already lowercased string
5917
			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
5918
			parse: function( execResult ) {
5919
				return [
5920
					parseInt( execResult[ 1 ], 16 ),
5921
					parseInt( execResult[ 2 ], 16 ),
5922
					parseInt( execResult[ 3 ], 16 )
5923
				];
5924
			}
5925
		}, {
5926
5927
			// This regex ignores A-F because it's compared against an already lowercased string
5928
			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
5929
			parse: function( execResult ) {
5930
				return [
5931
					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
5932
					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
5933
					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
5934
				];
5935
			}
5936
		}, {
5937
			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
5938
			space: "hsla",
5939
			parse: function( execResult ) {
5940
				return [
5941
					execResult[ 1 ],
5942
					execResult[ 2 ] / 100,
5943
					execResult[ 3 ] / 100,
5944
					execResult[ 4 ]
5945
				];
5946
			}
5947
		} ],
5948
5949
	// JQuery.Color( )
5950
	color = jQuery.Color = function( color, green, blue, alpha ) {
5951
		return new jQuery.Color.fn.parse( color, green, blue, alpha );
5952
	},
5953
	spaces = {
5954
		rgba: {
5955
			props: {
5956
				red: {
5957
					idx: 0,
5958
					type: "byte"
5959
				},
5960
				green: {
5961
					idx: 1,
5962
					type: "byte"
5963
				},
5964
				blue: {
5965
					idx: 2,
5966
					type: "byte"
5967
				}
5968
			}
5969
		},
5970
5971
		hsla: {
5972
			props: {
5973
				hue: {
5974
					idx: 0,
5975
					type: "degrees"
5976
				},
5977
				saturation: {
5978
					idx: 1,
5979
					type: "percent"
5980
				},
5981
				lightness: {
5982
					idx: 2,
5983
					type: "percent"
5984
				}
5985
			}
5986
		}
5987
	},
5988
	propTypes = {
5989
		"byte": {
5990
			floor: true,
5991
			max: 255
5992
		},
5993
		"percent": {
5994
			max: 1
5995
		},
5996
		"degrees": {
5997
			mod: 360,
5998
			floor: true
5999
		}
6000
	},
6001
	support = color.support = {},
6002
6003
	// Element for support tests
6004
	supportElem = jQuery( "<p>" )[ 0 ],
6005
6006
	// Colors = jQuery.Color.names
6007
	colors,
6008
6009
	// Local aliases of functions called often
6010
	each = jQuery.each;
6011
6012
// Determine rgba support immediately
6013
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
6014
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
6015
6016
// Define cache name and alpha properties
6017
// for rgba and hsla spaces
6018
each( spaces, function( spaceName, space ) {
6019
	space.cache = "_" + spaceName;
6020
	space.props.alpha = {
6021
		idx: 3,
6022
		type: "percent",
6023
		def: 1
6024
	};
6025
} );
6026
6027
function clamp( value, prop, allowEmpty ) {
6028
	var type = propTypes[ prop.type ] || {};
6029
6030
	if ( value == null ) {
0 ignored issues
show
Best Practice introduced by
Comparing value to null using the == operator is not safe. Consider using === instead.
Loading history...
6031
		return ( allowEmpty || !prop.def ) ? null : prop.def;
6032
	}
6033
6034
	// ~~ is an short way of doing floor for positive numbers
6035
	value = type.floor ? ~~value : parseFloat( value );
6036
6037
	// IE will pass in empty strings as value for alpha,
6038
	// which will hit this case
6039
	if ( isNaN( value ) ) {
6040
		return prop.def;
6041
	}
6042
6043
	if ( type.mod ) {
6044
6045
		// We add mod before modding to make sure that negatives values
6046
		// get converted properly: -10 -> 350
6047
		return ( value + type.mod ) % type.mod;
6048
	}
6049
6050
	// For now all property types without mod have min and max
6051
	return 0 > value ? 0 : type.max < value ? type.max : value;
6052
}
6053
6054
function stringParse( string ) {
6055
	var inst = color(),
6056
		rgba = inst._rgba = [];
6057
6058
	string = string.toLowerCase();
6059
6060
	each( stringParsers, function( i, parser ) {
6061
		var parsed,
6062
			match = parser.re.exec( string ),
6063
			values = match && parser.parse( match ),
6064
			spaceName = parser.space || "rgba";
6065
6066
		if ( values ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if values 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...
6067
			parsed = inst[ spaceName ]( values );
6068
6069
			// If this was an rgba parse the assignment might happen twice
6070
			// oh well....
6071
			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
6072
			rgba = inst._rgba = parsed._rgba;
6073
6074
			// Exit each( stringParsers ) here because we matched
6075
			return false;
6076
		}
6077
	} );
6078
6079
	// Found a stringParser that handled it
6080
	if ( rgba.length ) {
6081
6082
		// If this came from a parsed string, force "transparent" when alpha is 0
6083
		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
6084
		if ( rgba.join() === "0,0,0,0" ) {
6085
			jQuery.extend( rgba, colors.transparent );
6086
		}
6087
		return inst;
6088
	}
6089
6090
	// Named colors
6091
	return colors[ string ];
6092
}
6093
6094
color.fn = jQuery.extend( color.prototype, {
6095
	parse: function( red, green, blue, alpha ) {
6096
		if ( red === undefined ) {
6097
			this._rgba = [ null, null, null, null ];
6098
			return this;
6099
		}
6100
		if ( red.jquery || red.nodeType ) {
6101
			red = jQuery( red ).css( green );
6102
			green = undefined;
6103
		}
6104
6105
		var inst = this,
6106
			type = jQuery.type( red ),
6107
			rgba = this._rgba = [];
6108
6109
		// More than 1 argument specified - assume ( red, green, blue, alpha )
6110
		if ( green !== undefined ) {
6111
			red = [ red, green, blue, alpha ];
6112
			type = "array";
6113
		}
6114
6115
		if ( type === "string" ) {
6116
			return this.parse( stringParse( red ) || colors._default );
6117
		}
6118
6119
		if ( type === "array" ) {
6120
			each( spaces.rgba.props, function( key, prop ) {
6121
				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
6122
			} );
6123
			return this;
6124
		}
6125
6126
		if ( type === "object" ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if type === "object" 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...
6127
			if ( red instanceof color ) {
6128
				each( spaces, function( spaceName, space ) {
6129
					if ( red[ space.cache ] ) {
6130
						inst[ space.cache ] = red[ space.cache ].slice();
6131
					}
6132
				} );
6133
			} else {
6134
				each( spaces, function( spaceName, space ) {
6135
					var cache = space.cache;
6136
					each( space.props, function( key, prop ) {
6137
6138
						// If the cache doesn't exist, and we know how to convert
6139
						if ( !inst[ cache ] && space.to ) {
6140
6141
							// If the value was null, we don't need to copy it
6142
							// if the key was alpha, we don't need to copy it either
6143
							if ( key === "alpha" || red[ key ] == null ) {
0 ignored issues
show
Best Practice introduced by
Comparing red.key to null using the == operator is not safe. Consider using === instead.
Loading history...
6144
								return;
6145
							}
6146
							inst[ cache ] = space.to( inst._rgba );
6147
						}
6148
6149
						// This is the only case where we allow nulls for ALL properties.
6150
						// call clamp with alwaysAllowEmpty
6151
						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
6152
					} );
6153
6154
					// Everything defined but alpha?
6155
					if ( inst[ cache ] &&
6156
							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
6157
6158
						// Use the default of 1
6159
						inst[ cache ][ 3 ] = 1;
6160
						if ( space.from ) {
6161
							inst._rgba = space.from( inst[ cache ] );
6162
						}
6163
					}
6164
				} );
6165
			}
6166
			return this;
6167
		}
6168
	},
6169
	is: function( compare ) {
6170
		var is = color( compare ),
6171
			same = true,
6172
			inst = this;
6173
6174
		each( spaces, function( _, space ) {
6175
			var localCache,
6176
				isCache = is[ space.cache ];
6177
			if ( isCache ) {
6178
				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
6179
				each( space.props, function( _, prop ) {
6180
					if ( isCache[ prop.idx ] != null ) {
0 ignored issues
show
Complexity Best Practice introduced by
There is no return statement if isCache.prop.idx != null 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...
Best Practice introduced by
Comparing isCache.prop.idx to null using the != operator is not safe. Consider using !== instead.
Loading history...
6181
						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
6182
						return same;
6183
					}
6184
				} );
6185
			}
6186
			return same;
6187
		} );
6188
		return same;
6189
	},
6190
	_space: function() {
6191
		var used = [],
6192
			inst = this;
6193
		each( spaces, function( spaceName, space ) {
6194
			if ( inst[ space.cache ] ) {
6195
				used.push( spaceName );
6196
			}
6197
		} );
6198
		return used.pop();
6199
	},
6200
	transition: function( other, distance ) {
6201
		var end = color( other ),
6202
			spaceName = end._space(),
6203
			space = spaces[ spaceName ],
6204
			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
6205
			start = startColor[ space.cache ] || space.to( startColor._rgba ),
6206
			result = start.slice();
6207
6208
		end = end[ space.cache ];
6209
		each( space.props, function( key, prop ) {
6210
			var index = prop.idx,
6211
				startValue = start[ index ],
6212
				endValue = end[ index ],
6213
				type = propTypes[ prop.type ] || {};
6214
6215
			// If null, don't override start value
6216
			if ( endValue === null ) {
6217
				return;
6218
			}
6219
6220
			// If null - use end
6221
			if ( startValue === null ) {
6222
				result[ index ] = endValue;
6223
			} else {
6224
				if ( type.mod ) {
6225
					if ( endValue - startValue > type.mod / 2 ) {
6226
						startValue += type.mod;
6227
					} else if ( startValue - endValue > type.mod / 2 ) {
6228
						startValue -= type.mod;
6229
					}
6230
				}
6231
				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
6232
			}
6233
		} );
6234
		return this[ spaceName ]( result );
6235
	},
6236
	blend: function( opaque ) {
6237
6238
		// If we are already opaque - return ourself
6239
		if ( this._rgba[ 3 ] === 1 ) {
6240
			return this;
6241
		}
6242
6243
		var rgb = this._rgba.slice(),
6244
			a = rgb.pop(),
6245
			blend = color( opaque )._rgba;
6246
6247
		return color( jQuery.map( rgb, function( v, i ) {
6248
			return ( 1 - a ) * blend[ i ] + a * v;
6249
		} ) );
6250
	},
6251
	toRgbaString: function() {
6252
		var prefix = "rgba(",
6253
			rgba = jQuery.map( this._rgba, function( v, i ) {
6254
				return v == null ? ( i > 2 ? 1 : 0 ) : v;
0 ignored issues
show
Best Practice introduced by
Comparing v to null using the == operator is not safe. Consider using === instead.
Loading history...
6255
			} );
6256
6257
		if ( rgba[ 3 ] === 1 ) {
6258
			rgba.pop();
6259
			prefix = "rgb(";
6260
		}
6261
6262
		return prefix + rgba.join() + ")";
6263
	},
6264
	toHslaString: function() {
6265
		var prefix = "hsla(",
6266
			hsla = jQuery.map( this.hsla(), function( v, i ) {
6267
				if ( v == null ) {
0 ignored issues
show
Best Practice introduced by
Comparing v to null using the == operator is not safe. Consider using === instead.
Loading history...
6268
					v = i > 2 ? 1 : 0;
6269
				}
6270
6271
				// Catch 1 and 2
6272
				if ( i && i < 3 ) {
6273
					v = Math.round( v * 100 ) + "%";
6274
				}
6275
				return v;
6276
			} );
6277
6278
		if ( hsla[ 3 ] === 1 ) {
6279
			hsla.pop();
6280
			prefix = "hsl(";
6281
		}
6282
		return prefix + hsla.join() + ")";
6283
	},
6284
	toHexString: function( includeAlpha ) {
6285
		var rgba = this._rgba.slice(),
6286
			alpha = rgba.pop();
6287
6288
		if ( includeAlpha ) {
6289
			rgba.push( ~~( alpha * 255 ) );
6290
		}
6291
6292
		return "#" + jQuery.map( rgba, function( v ) {
6293
6294
			// Default to 0 when nulls exist
6295
			v = ( v || 0 ).toString( 16 );
6296
			return v.length === 1 ? "0" + v : v;
6297
		} ).join( "" );
6298
	},
6299
	toString: function() {
6300
		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
6301
	}
6302
} );
6303
color.fn.parse.prototype = color.fn;
6304
6305
// Hsla conversions adapted from:
6306
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
6307
6308
function hue2rgb( p, q, h ) {
6309
	h = ( h + 1 ) % 1;
6310
	if ( h * 6 < 1 ) {
6311
		return p + ( q - p ) * h * 6;
6312
	}
6313
	if ( h * 2 < 1 ) {
6314
		return q;
6315
	}
6316
	if ( h * 3 < 2 ) {
6317
		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
6318
	}
6319
	return p;
6320
}
6321
6322
spaces.hsla.to = function( rgba ) {
6323
	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
0 ignored issues
show
Best Practice introduced by
Comparing rgba.0 to null using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing rgba.2 to null using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing rgba.1 to null using the == operator is not safe. Consider using === instead.
Loading history...
6324
		return [ null, null, null, rgba[ 3 ] ];
6325
	}
6326
	var r = rgba[ 0 ] / 255,
6327
		g = rgba[ 1 ] / 255,
6328
		b = rgba[ 2 ] / 255,
6329
		a = rgba[ 3 ],
6330
		max = Math.max( r, g, b ),
6331
		min = Math.min( r, g, b ),
6332
		diff = max - min,
6333
		add = max + min,
6334
		l = add * 0.5,
6335
		h, s;
6336
6337
	if ( min === max ) {
6338
		h = 0;
6339
	} else if ( r === max ) {
6340
		h = ( 60 * ( g - b ) / diff ) + 360;
6341
	} else if ( g === max ) {
6342
		h = ( 60 * ( b - r ) / diff ) + 120;
6343
	} else {
6344
		h = ( 60 * ( r - g ) / diff ) + 240;
6345
	}
6346
6347
	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
6348
	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
6349
	if ( diff === 0 ) {
6350
		s = 0;
6351
	} else if ( l <= 0.5 ) {
6352
		s = diff / add;
6353
	} else {
6354
		s = diff / ( 2 - add );
6355
	}
6356
	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
0 ignored issues
show
Best Practice introduced by
Comparing a to null using the == operator is not safe. Consider using === instead.
Loading history...
6357
};
6358
6359
spaces.hsla.from = function( hsla ) {
6360
	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
0 ignored issues
show
Best Practice introduced by
Comparing hsla.0 to null using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing hsla.1 to null using the == operator is not safe. Consider using === instead.
Loading history...
Best Practice introduced by
Comparing hsla.2 to null using the == operator is not safe. Consider using === instead.
Loading history...
6361
		return [ null, null, null, hsla[ 3 ] ];
6362
	}
6363
	var h = hsla[ 0 ] / 360,
6364
		s = hsla[ 1 ],
6365
		l = hsla[ 2 ],
6366
		a = hsla[ 3 ],
6367
		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
6368
		p = 2 * l - q;
6369
6370
	return [
6371
		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
6372
		Math.round( hue2rgb( p, q, h ) * 255 ),
6373
		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
6374
		a
6375
	];
6376
};
6377
6378
each( spaces, function( spaceName, space ) {
6379
	var props = space.props,
6380
		cache = space.cache,
6381
		to = space.to,
6382
		from = space.from;
6383
6384
	// Makes rgba() and hsla()
6385
	color.fn[ spaceName ] = function( value ) {
6386
6387
		// Generate a cache for this space if it doesn't exist
6388
		if ( to && !this[ cache ] ) {
6389
			this[ cache ] = to( this._rgba );
6390
		}
6391
		if ( value === undefined ) {
6392
			return this[ cache ].slice();
6393
		}
6394
6395
		var ret,
6396
			type = jQuery.type( value ),
6397
			arr = ( type === "array" || type === "object" ) ? value : arguments,
6398
			local = this[ cache ].slice();
6399
6400
		each( props, function( key, prop ) {
6401
			var val = arr[ type === "object" ? key : prop.idx ];
6402
			if ( val == null ) {
0 ignored issues
show
Best Practice introduced by
Comparing val to null using the == operator is not safe. Consider using === instead.
Loading history...
6403
				val = local[ prop.idx ];
6404
			}
6405
			local[ prop.idx ] = clamp( val, prop );
6406
		} );
6407
6408
		if ( from ) {
6409
			ret = color( from( local ) );
6410
			ret[ cache ] = local;
6411
			return ret;
6412
		} 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...
6413
			return color( local );
6414
		}
6415
	};
6416
6417
	// Makes red() green() blue() alpha() hue() saturation() lightness()
6418
	each( props, function( key, prop ) {
6419
6420
		// Alpha is included in more than one space
6421
		if ( color.fn[ key ] ) {
6422
			return;
6423
		}
6424
		color.fn[ key ] = function( value ) {
6425
			var vtype = jQuery.type( value ),
6426
				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
6427
				local = this[ fn ](),
6428
				cur = local[ prop.idx ],
6429
				match;
6430
6431
			if ( vtype === "undefined" ) {
6432
				return cur;
6433
			}
6434
6435
			if ( vtype === "function" ) {
6436
				value = value.call( this, cur );
6437
				vtype = jQuery.type( value );
6438
			}
6439
			if ( value == null && prop.empty ) {
0 ignored issues
show
Best Practice introduced by
Comparing value to null using the == operator is not safe. Consider using === instead.
Loading history...
6440
				return this;
6441
			}
6442
			if ( vtype === "string" ) {
6443
				match = rplusequals.exec( value );
6444
				if ( match ) {
6445
					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
6446
				}
6447
			}
6448
			local[ prop.idx ] = value;
6449
			return this[ fn ]( local );
6450
		};
6451
	} );
6452
} );
6453
6454
// Add cssHook and .fx.step function for each named hook.
6455
// accept a space separated string of properties
6456
color.hook = function( hook ) {
6457
	var hooks = hook.split( " " );
6458
	each( hooks, function( i, hook ) {
6459
		jQuery.cssHooks[ hook ] = {
6460
			set: function( elem, value ) {
6461
				var parsed, curElem,
6462
					backgroundColor = "";
6463
6464
				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
6465
						( parsed = stringParse( value ) ) ) ) {
6466
					value = color( parsed || value );
6467
					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
6468
						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
6469
						while (
6470
							( backgroundColor === "" || backgroundColor === "transparent" ) &&
6471
							curElem && curElem.style
6472
						) {
6473
							try {
6474
								backgroundColor = jQuery.css( curElem, "backgroundColor" );
6475
								curElem = curElem.parentNode;
6476
							} 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...
6477
							}
6478
						}
6479
6480
						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
6481
							backgroundColor :
6482
							"_default" );
6483
					}
6484
6485
					value = value.toRgbaString();
6486
				}
6487
				try {
6488
					elem.style[ hook ] = value;
6489
				} 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...
6490
6491
					// Wrapped to prevent IE from throwing errors on "invalid" values like
6492
					// 'auto' or 'inherit'
6493
				}
6494
			}
6495
		};
6496
		jQuery.fx.step[ hook ] = function( fx ) {
6497
			if ( !fx.colorInit ) {
6498
				fx.start = color( fx.elem, hook );
6499
				fx.end = color( fx.end );
6500
				fx.colorInit = true;
6501
			}
6502
			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
6503
		};
6504
	} );
6505
6506
};
6507
6508
color.hook( stepHooks );
6509
6510
jQuery.cssHooks.borderColor = {
6511
	expand: function( value ) {
6512
		var expanded = {};
6513
6514
		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
6515
			expanded[ "border" + part + "Color" ] = value;
6516
		} );
6517
		return expanded;
6518
	}
6519
};
6520
6521
// Basic color names only.
6522
// Usage of any of the other color names requires adding yourself or including
6523
// jquery.color.svg-names.js.
6524
colors = jQuery.Color.names = {
6525
6526
	// 4.1. Basic color keywords
6527
	aqua: "#00ffff",
6528
	black: "#000000",
6529
	blue: "#0000ff",
6530
	fuchsia: "#ff00ff",
6531
	gray: "#808080",
6532
	green: "#008000",
6533
	lime: "#00ff00",
6534
	maroon: "#800000",
6535
	navy: "#000080",
6536
	olive: "#808000",
6537
	purple: "#800080",
6538
	red: "#ff0000",
6539
	silver: "#c0c0c0",
6540
	teal: "#008080",
6541
	white: "#ffffff",
6542
	yellow: "#ffff00",
6543
6544
	// 4.2.3. "transparent" color keyword
6545
	transparent: [ null, null, null, 0 ],
6546
6547
	_default: "#ffffff"
6548
};
6549
6550
} )( jQuery );
6551
6552
/******************************************************************************/
6553
/****************************** CLASS ANIMATIONS ******************************/
6554
/******************************************************************************/
6555
( function() {
6556
6557
var classAnimationActions = [ "add", "remove", "toggle" ],
6558
	shorthandStyles = {
6559
		border: 1,
6560
		borderBottom: 1,
6561
		borderColor: 1,
6562
		borderLeft: 1,
6563
		borderRight: 1,
6564
		borderTop: 1,
6565
		borderWidth: 1,
6566
		margin: 1,
6567
		padding: 1
6568
	};
6569
6570
$.each(
6571
	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
6572
	function( _, prop ) {
6573
		$.fx.step[ prop ] = function( fx ) {
6574
			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
6575
				jQuery.style( fx.elem, prop, fx.end );
6576
				fx.setAttr = true;
6577
			}
6578
		};
6579
	}
6580
);
6581
6582
function getElementStyles( elem ) {
6583
	var key, len,
6584
		style = elem.ownerDocument.defaultView ?
6585
			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
6586
			elem.currentStyle,
6587
		styles = {};
6588
6589
	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
6590
		len = style.length;
6591
		while ( len-- ) {
6592
			key = style[ len ];
6593
			if ( typeof style[ key ] === "string" ) {
6594
				styles[ $.camelCase( key ) ] = style[ key ];
6595
			}
6596
		}
6597
6598
	// Support: Opera, IE <9
6599
	} else {
6600
		for ( key in style ) {
6601
			if ( typeof style[ key ] === "string" ) {
6602
				styles[ key ] = style[ key ];
6603
			}
6604
		}
6605
	}
6606
6607
	return styles;
6608
}
6609
6610
function styleDifference( oldStyle, newStyle ) {
6611
	var diff = {},
6612
		name, value;
6613
6614
	for ( name in newStyle ) {
6615
		value = newStyle[ name ];
6616
		if ( oldStyle[ name ] !== value ) {
6617
			if ( !shorthandStyles[ name ] ) {
6618
				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
6619
					diff[ name ] = value;
6620
				}
6621
			}
6622
		}
6623
	}
6624
6625
	return diff;
6626
}
6627
6628
// Support: jQuery <1.8
6629
if ( !$.fn.addBack ) {
6630
	$.fn.addBack = function( selector ) {
6631
		return this.add( selector == null ?
0 ignored issues
show
Best Practice introduced by
Comparing selector to null using the == operator is not safe. Consider using === instead.
Loading history...
6632
			this.prevObject : this.prevObject.filter( selector )
6633
		);
6634
	};
6635
}
6636
6637
$.effects.animateClass = function( value, duration, easing, callback ) {
6638
	var o = $.speed( duration, easing, callback );
6639
6640
	return this.queue( function() {
6641
		var animated = $( this ),
6642
			baseClass = animated.attr( "class" ) || "",
6643
			applyClassChange,
6644
			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
6645
6646
		// Map the animated objects to store the original styles.
6647
		allAnimations = allAnimations.map( function() {
6648
			var el = $( this );
6649
			return {
6650
				el: el,
6651
				start: getElementStyles( this )
6652
			};
6653
		} );
6654
6655
		// Apply class change
6656
		applyClassChange = function() {
6657
			$.each( classAnimationActions, function( i, action ) {
6658
				if ( value[ action ] ) {
6659
					animated[ action + "Class" ]( value[ action ] );
6660
				}
6661
			} );
6662
		};
6663
		applyClassChange();
6664
6665
		// Map all animated objects again - calculate new styles and diff
6666
		allAnimations = allAnimations.map( function() {
6667
			this.end = getElementStyles( this.el[ 0 ] );
6668
			this.diff = styleDifference( this.start, this.end );
6669
			return this;
6670
		} );
6671
6672
		// Apply original class
6673
		animated.attr( "class", baseClass );
6674
6675
		// Map all animated objects again - this time collecting a promise
6676
		allAnimations = allAnimations.map( function() {
6677
			var styleInfo = this,
6678
				dfd = $.Deferred(),
6679
				opts = $.extend( {}, o, {
6680
					queue: false,
6681
					complete: function() {
6682
						dfd.resolve( styleInfo );
6683
					}
6684
				} );
6685
6686
			this.el.animate( this.diff, opts );
6687
			return dfd.promise();
6688
		} );
6689
6690
		// Once all animations have completed:
6691
		$.when.apply( $, allAnimations.get() ).done( function() {
6692
6693
			// Set the final class
6694
			applyClassChange();
6695
6696
			// For each animated element,
6697
			// clear all css properties that were animated
6698
			$.each( arguments, function() {
6699
				var el = this.el;
6700
				$.each( this.diff, function( key ) {
6701
					el.css( key, "" );
6702
				} );
6703
			} );
6704
6705
			// This is guarnteed to be there if you use jQuery.speed()
6706
			// it also handles dequeuing the next anim...
6707
			o.complete.call( animated[ 0 ] );
6708
		} );
6709
	} );
6710
};
6711
6712
$.fn.extend( {
6713
	addClass: ( function( orig ) {
6714
		return function( classNames, speed, easing, callback ) {
6715
			return speed ?
6716
				$.effects.animateClass.call( this,
6717
					{ add: classNames }, speed, easing, callback ) :
6718
				orig.apply( this, arguments );
6719
		};
6720
	} )( $.fn.addClass ),
6721
6722
	removeClass: ( function( orig ) {
6723
		return function( classNames, speed, easing, callback ) {
6724
			return arguments.length > 1 ?
6725
				$.effects.animateClass.call( this,
6726
					{ remove: classNames }, speed, easing, callback ) :
6727
				orig.apply( this, arguments );
6728
		};
6729
	} )( $.fn.removeClass ),
6730
6731
	toggleClass: ( function( orig ) {
6732
		return function( classNames, force, speed, easing, callback ) {
6733
			if ( typeof force === "boolean" || force === undefined ) {
6734
				if ( !speed ) {
6735
6736
					// Without speed parameter
6737
					return orig.apply( this, arguments );
6738
				} 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...
6739
					return $.effects.animateClass.call( this,
6740
						( force ? { add: classNames } : { remove: classNames } ),
6741
						speed, easing, callback );
6742
				}
6743
			} 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...
6744
6745
				// Without force parameter
6746
				return $.effects.animateClass.call( this,
6747
					{ toggle: classNames }, force, speed, easing );
6748
			}
6749
		};
6750
	} )( $.fn.toggleClass ),
6751
6752
	switchClass: function( remove, add, speed, easing, callback ) {
6753
		return $.effects.animateClass.call( this, {
6754
			add: add,
6755
			remove: remove
6756
		}, speed, easing, callback );
6757
	}
6758
} );
6759
6760
} )();
6761
6762
/******************************************************************************/
6763
/*********************************** EFFECTS **********************************/
6764
/******************************************************************************/
6765
6766
( function() {
6767
6768
if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
6769
	$.expr.filters.animated = ( function( orig ) {
6770
		return function( elem ) {
6771
			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
6772
		};
6773
	} )( $.expr.filters.animated );
6774
}
6775
6776
if ( $.uiBackCompat !== false ) {
6777
	$.extend( $.effects, {
6778
6779
		// Saves a set of properties in a data storage
6780
		save: function( element, set ) {
6781
			var i = 0, length = set.length;
6782
			for ( ; i < length; i++ ) {
6783
				if ( set[ i ] !== null ) {
6784
					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
6785
				}
6786
			}
6787
		},
6788
6789
		// Restores a set of previously saved properties from a data storage
6790
		restore: function( element, set ) {
6791
			var val, i = 0, length = set.length;
6792
			for ( ; i < length; i++ ) {
6793
				if ( set[ i ] !== null ) {
6794
					val = element.data( dataSpace + set[ i ] );
6795
					element.css( set[ i ], val );
6796
				}
6797
			}
6798
		},
6799
6800
		setMode: function( el, mode ) {
6801
			if ( mode === "toggle" ) {
6802
				mode = el.is( ":hidden" ) ? "show" : "hide";
6803
			}
6804
			return mode;
6805
		},
6806
6807
		// Wraps the element around a wrapper that copies position properties
6808
		createWrapper: function( element ) {
6809
6810
			// If the element is already wrapped, return it
6811
			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
6812
				return element.parent();
6813
			}
6814
6815
			// Wrap the element
6816
			var props = {
6817
					width: element.outerWidth( true ),
6818
					height: element.outerHeight( true ),
6819
					"float": element.css( "float" )
6820
				},
6821
				wrapper = $( "<div></div>" )
6822
					.addClass( "ui-effects-wrapper" )
6823
					.css( {
6824
						fontSize: "100%",
6825
						background: "transparent",
6826
						border: "none",
6827
						margin: 0,
6828
						padding: 0
6829
					} ),
6830
6831
				// Store the size in case width/height are defined in % - Fixes #5245
6832
				size = {
6833
					width: element.width(),
6834
					height: element.height()
6835
				},
6836
				active = document.activeElement;
6837
6838
			// Support: Firefox
6839
			// Firefox incorrectly exposes anonymous content
6840
			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
6841
			try {
6842
				active.id;
0 ignored issues
show
introduced by
The result of the property access to active.id is not used.
Loading history...
6843
			} catch ( e ) {
6844
				active = document.body;
6845
			}
6846
6847
			element.wrap( wrapper );
6848
6849
			// Fixes #7595 - Elements lose focus when wrapped.
6850
			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
6851
				$( active ).trigger( "focus" );
6852
			}
6853
6854
			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
6855
			// lose the reference to the wrapped element
6856
			wrapper = element.parent();
6857
6858
			// Transfer positioning properties to the wrapper
6859
			if ( element.css( "position" ) === "static" ) {
6860
				wrapper.css( { position: "relative" } );
6861
				element.css( { position: "relative" } );
6862
			} else {
6863
				$.extend( props, {
6864
					position: element.css( "position" ),
6865
					zIndex: element.css( "z-index" )
6866
				} );
6867
				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
6868
					props[ pos ] = element.css( pos );
6869
					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
6870
						props[ pos ] = "auto";
6871
					}
6872
				} );
6873
				element.css( {
6874
					position: "relative",
6875
					top: 0,
6876
					left: 0,
6877
					right: "auto",
6878
					bottom: "auto"
6879
				} );
6880
			}
6881
			element.css( size );
6882
6883
			return wrapper.css( props ).show();
6884
		},
6885
6886
		removeWrapper: function( element ) {
6887
			var active = document.activeElement;
6888
6889
			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
6890
				element.parent().replaceWith( element );
6891
6892
				// Fixes #7595 - Elements lose focus when wrapped.
6893
				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
6894
					$( active ).trigger( "focus" );
6895
				}
6896
			}
6897
6898
			return element;
6899
		}
6900
	} );
6901
}
6902
6903
$.extend( $.effects, {
6904
	version: "1.12.0",
6905
6906
	define: function( name, mode, effect ) {
6907
		if ( !effect ) {
6908
			effect = mode;
6909
			mode = "effect";
6910
		}
6911
6912
		$.effects.effect[ name ] = effect;
6913
		$.effects.effect[ name ].mode = mode;
6914
6915
		return effect;
6916
	},
6917
6918
	scaledDimensions: function( element, percent, direction ) {
6919
		if ( percent === 0 ) {
6920
			return {
6921
				height: 0,
6922
				width: 0,
6923
				outerHeight: 0,
6924
				outerWidth: 0
6925
			};
6926
		}
6927
6928
		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
6929
			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
6930
6931
		return {
6932
			height: element.height() * y,
6933
			width: element.width() * x,
6934
			outerHeight: element.outerHeight() * y,
6935
			outerWidth: element.outerWidth() * x
6936
		};
6937
6938
	},
6939
6940
	clipToBox: function( animation ) {
6941
		return {
6942
			width: animation.clip.right - animation.clip.left,
6943
			height: animation.clip.bottom - animation.clip.top,
6944
			left: animation.clip.left,
6945
			top: animation.clip.top
6946
		};
6947
	},
6948
6949
	// Injects recently queued functions to be first in line (after "inprogress")
6950
	unshift: function( element, queueLength, count ) {
6951
		var queue = element.queue();
6952
6953
		if ( queueLength > 1 ) {
6954
			queue.splice.apply( queue,
6955
				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
6956
		}
6957
		element.dequeue();
6958
	},
6959
6960
	saveStyle: function( element ) {
6961
		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
6962
	},
6963
6964
	restoreStyle: function( element ) {
6965
		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
6966
		element.removeData( dataSpaceStyle );
6967
	},
6968
6969
	mode: function( element, mode ) {
6970
		var hidden = element.is( ":hidden" );
6971
6972
		if ( mode === "toggle" ) {
6973
			mode = hidden ? "show" : "hide";
6974
		}
6975
		if ( hidden ? mode === "hide" : mode === "show" ) {
6976
			mode = "none";
6977
		}
6978
		return mode;
6979
	},
6980
6981
	// Translates a [top,left] array into a baseline value
6982
	getBaseline: function( origin, original ) {
6983
		var y, x;
6984
6985
		switch ( origin[ 0 ] ) {
6986
		case "top":
6987
			y = 0;
6988
			break;
6989
		case "middle":
6990
			y = 0.5;
6991
			break;
6992
		case "bottom":
6993
			y = 1;
6994
			break;
6995
		default:
6996
			y = origin[ 0 ] / original.height;
6997
		}
6998
6999
		switch ( origin[ 1 ] ) {
7000
		case "left":
7001
			x = 0;
7002
			break;
7003
		case "center":
7004
			x = 0.5;
7005
			break;
7006
		case "right":
7007
			x = 1;
7008
			break;
7009
		default:
7010
			x = origin[ 1 ] / original.width;
7011
		}
7012
7013
		return {
7014
			x: x,
7015
			y: y
7016
		};
7017
	},
7018
7019
	// Creates a placeholder element so that the original element can be made absolute
7020
	createPlaceholder: function( element ) {
7021
		var placeholder,
7022
			cssPosition = element.css( "position" ),
7023
			position = element.position();
7024
7025
		// Lock in margins first to account for form elements, which
7026
		// will change margin if you explicitly set height
7027
		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
7028
		// Support: Safari
7029
		element.css( {
7030
			marginTop: element.css( "marginTop" ),
7031
			marginBottom: element.css( "marginBottom" ),
7032
			marginLeft: element.css( "marginLeft" ),
7033
			marginRight: element.css( "marginRight" )
7034
		} )
7035
		.outerWidth( element.outerWidth() )
7036
		.outerHeight( element.outerHeight() );
7037
7038
		if ( /^(static|relative)/.test( cssPosition ) ) {
7039
			cssPosition = "absolute";
7040
7041
			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
7042
7043
				// Convert inline to inline block to account for inline elements
7044
				// that turn to inline block based on content (like img)
7045
				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
7046
					"inline-block" :
7047
					"block",
7048
				visibility: "hidden",
7049
7050
				// Margins need to be set to account for margin collapse
7051
				marginTop: element.css( "marginTop" ),
7052
				marginBottom: element.css( "marginBottom" ),
7053
				marginLeft: element.css( "marginLeft" ),
7054
				marginRight: element.css( "marginRight" ),
7055
				"float": element.css( "float" )
7056
			} )
7057
			.outerWidth( element.outerWidth() )
7058
			.outerHeight( element.outerHeight() )
7059
			.addClass( "ui-effects-placeholder" );
7060
7061
			element.data( dataSpace + "placeholder", placeholder );
7062
		}
7063
7064
		element.css( {
7065
			position: cssPosition,
7066
			left: position.left,
7067
			top: position.top
7068
		} );
7069
7070
		return placeholder;
0 ignored issues
show
Bug introduced by
The variable placeholder does not seem to be initialized in case ^(static|relative).test(cssPosition) on line 7038 is false. Are you sure this can never be the case?
Loading history...
7071
	},
7072
7073
	removePlaceholder: function( element ) {
7074
		var dataKey = dataSpace + "placeholder",
7075
				placeholder = element.data( dataKey );
7076
7077
		if ( placeholder ) {
7078
			placeholder.remove();
7079
			element.removeData( dataKey );
7080
		}
7081
	},
7082
7083
	// Removes a placeholder if it exists and restores
7084
	// properties that were modified during placeholder creation
7085
	cleanUp: function( element ) {
7086
		$.effects.restoreStyle( element );
7087
		$.effects.removePlaceholder( element );
7088
	},
7089
7090
	setTransition: function( element, list, factor, value ) {
7091
		value = value || {};
7092
		$.each( list, function( i, x ) {
7093
			var unit = element.cssUnit( x );
7094
			if ( unit[ 0 ] > 0 ) {
7095
				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
7096
			}
7097
		} );
7098
		return value;
7099
	}
7100
} );
7101
7102
// Return an effect options object for the given parameters:
7103
function _normalizeArguments( effect, options, speed, callback ) {
7104
7105
	// Allow passing all options as the first parameter
7106
	if ( $.isPlainObject( effect ) ) {
7107
		options = effect;
7108
		effect = effect.effect;
7109
	}
7110
7111
	// Convert to an object
7112
	effect = { effect: effect };
7113
7114
	// Catch (effect, null, ...)
7115
	if ( options == null ) {
0 ignored issues
show
Best Practice introduced by
Comparing options to null using the == operator is not safe. Consider using === instead.
Loading history...
7116
		options = {};
7117
	}
7118
7119
	// Catch (effect, callback)
7120
	if ( $.isFunction( options ) ) {
7121
		callback = options;
7122
		speed = null;
7123
		options = {};
7124
	}
7125
7126
	// Catch (effect, speed, ?)
7127
	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
7128
		callback = speed;
7129
		speed = options;
7130
		options = {};
7131
	}
7132
7133
	// Catch (effect, options, callback)
7134
	if ( $.isFunction( speed ) ) {
7135
		callback = speed;
7136
		speed = null;
7137
	}
7138
7139
	// Add options to effect
7140
	if ( options ) {
7141
		$.extend( effect, options );
7142
	}
7143
7144
	speed = speed || options.duration;
7145
	effect.duration = $.fx.off ? 0 :
7146
		typeof speed === "number" ? speed :
7147
		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
7148
		$.fx.speeds._default;
7149
7150
	effect.complete = callback || options.complete;
7151
7152
	return effect;
7153
}
7154
7155
function standardAnimationOption( option ) {
7156
7157
	// Valid standard speeds (nothing, number, named speed)
7158
	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
7159
		return true;
7160
	}
7161
7162
	// Invalid strings - treat as "normal" speed
7163
	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
7164
		return true;
7165
	}
7166
7167
	// Complete callback
7168
	if ( $.isFunction( option ) ) {
7169
		return true;
7170
	}
7171
7172
	// Options hash (but not naming an effect)
7173
	if ( typeof option === "object" && !option.effect ) {
7174
		return true;
7175
	}
7176
7177
	// Didn't match any standard API
7178
	return false;
7179
}
7180
7181
$.fn.extend( {
7182
	effect: function( /* effect, options, speed, callback */ ) {
7183
		var args = _normalizeArguments.apply( this, arguments ),
7184
			effectMethod = $.effects.effect[ args.effect ],
7185
			defaultMode = effectMethod.mode,
7186
			queue = args.queue,
7187
			queueName = queue || "fx",
7188
			complete = args.complete,
7189
			mode = args.mode,
7190
			modes = [],
7191
			prefilter = function( next ) {
7192
				var el = $( this ),
7193
					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
7194
7195
				// Sentinel for duck-punching the :animated psuedo-selector
7196
				el.data( dataSpaceAnimated, true );
7197
7198
				// Save effect mode for later use,
7199
				// we can't just call $.effects.mode again later,
7200
				// as the .show() below destroys the initial state
7201
				modes.push( normalizedMode );
7202
7203
				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
7204
				if ( defaultMode && ( normalizedMode === "show" ||
7205
						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
7206
					el.show();
7207
				}
7208
7209
				if ( !defaultMode || normalizedMode !== "none" ) {
7210
					$.effects.saveStyle( el );
7211
				}
7212
7213
				if ( $.isFunction( next ) ) {
7214
					next();
7215
				}
7216
			};
7217
7218
		if ( $.fx.off || !effectMethod ) {
7219
7220
			// Delegate to the original method (e.g., .show()) if possible
7221
			if ( mode ) {
7222
				return this[ mode ]( args.duration, complete );
7223
			} 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...
7224
				return this.each( function() {
7225
					if ( complete ) {
7226
						complete.call( this );
7227
					}
7228
				} );
7229
			}
7230
		}
7231
7232
		function run( next ) {
7233
			var elem = $( this );
7234
7235
			function cleanup() {
7236
				elem.removeData( dataSpaceAnimated );
7237
7238
				$.effects.cleanUp( elem );
7239
7240
				if ( args.mode === "hide" ) {
7241
					elem.hide();
7242
				}
7243
7244
				done();
7245
			}
7246
7247
			function done() {
7248
				if ( $.isFunction( complete ) ) {
7249
					complete.call( elem[ 0 ] );
7250
				}
7251
7252
				if ( $.isFunction( next ) ) {
7253
					next();
7254
				}
7255
			}
7256
7257
			// Override mode option on a per element basis,
7258
			// as toggle can be either show or hide depending on element state
7259
			args.mode = modes.shift();
7260
7261
			if ( $.uiBackCompat !== false && !defaultMode ) {
7262
				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
7263
7264
					// Call the core method to track "olddisplay" properly
7265
					elem[ mode ]();
7266
					done();
7267
				} else {
7268
					effectMethod.call( elem[ 0 ], args, done );
7269
				}
7270
			} else {
7271
				if ( args.mode === "none" ) {
7272
7273
					// Call the core method to track "olddisplay" properly
7274
					elem[ mode ]();
7275
					done();
7276
				} else {
7277
					effectMethod.call( elem[ 0 ], args, cleanup );
7278
				}
7279
			}
7280
		}
7281
7282
		// Run prefilter on all elements first to ensure that
7283
		// any showing or hiding happens before placeholder creation,
7284
		// which ensures that any layout changes are correctly captured.
7285
		return queue === false ?
7286
			this.each( prefilter ).each( run ) :
7287
			this.queue( queueName, prefilter ).queue( queueName, run );
7288
	},
7289
7290
	show: ( function( orig ) {
7291
		return function( option ) {
7292
			if ( standardAnimationOption( option ) ) {
7293
				return orig.apply( this, arguments );
7294
			} 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...
7295
				var args = _normalizeArguments.apply( this, arguments );
7296
				args.mode = "show";
7297
				return this.effect.call( this, args );
7298
			}
7299
		};
7300
	} )( $.fn.show ),
7301
7302
	hide: ( function( orig ) {
7303
		return function( option ) {
7304
			if ( standardAnimationOption( option ) ) {
7305
				return orig.apply( this, arguments );
7306
			} 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...
7307
				var args = _normalizeArguments.apply( this, arguments );
7308
				args.mode = "hide";
7309
				return this.effect.call( this, args );
7310
			}
7311
		};
7312
	} )( $.fn.hide ),
7313
7314
	toggle: ( function( orig ) {
7315
		return function( option ) {
7316
			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
7317
				return orig.apply( this, arguments );
7318
			} 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...
7319
				var args = _normalizeArguments.apply( this, arguments );
7320
				args.mode = "toggle";
7321
				return this.effect.call( this, args );
7322
			}
7323
		};
7324
	} )( $.fn.toggle ),
7325
7326
	cssUnit: function( key ) {
7327
		var style = this.css( key ),
7328
			val = [];
7329
7330
		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
7331
			if ( style.indexOf( unit ) > 0 ) {
7332
				val = [ parseFloat( style ), unit ];
7333
			}
7334
		} );
7335
		return val;
7336
	},
7337
7338
	cssClip: function( clipObj ) {
7339
		if ( clipObj ) {
7340
			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
7341
				clipObj.bottom + "px " + clipObj.left + "px)" );
7342
		}
7343
		return parseClip( this.css( "clip" ), this );
7344
	},
7345
7346
	transfer: function( options, done ) {
7347
		var element = $( this ),
7348
			target = $( options.to ),
7349
			targetFixed = target.css( "position" ) === "fixed",
7350
			body = $( "body" ),
7351
			fixTop = targetFixed ? body.scrollTop() : 0,
7352
			fixLeft = targetFixed ? body.scrollLeft() : 0,
7353
			endPosition = target.offset(),
7354
			animation = {
7355
				top: endPosition.top - fixTop,
7356
				left: endPosition.left - fixLeft,
7357
				height: target.innerHeight(),
7358
				width: target.innerWidth()
7359
			},
7360
			startPosition = element.offset(),
7361
			transfer = $( "<div class='ui-effects-transfer'></div>" )
7362
				.appendTo( "body" )
7363
				.addClass( options.className )
7364
				.css( {
7365
					top: startPosition.top - fixTop,
7366
					left: startPosition.left - fixLeft,
7367
					height: element.innerHeight(),
7368
					width: element.innerWidth(),
7369
					position: targetFixed ? "fixed" : "absolute"
7370
				} )
7371
				.animate( animation, options.duration, options.easing, function() {
7372
					transfer.remove();
7373
					if ( $.isFunction( done ) ) {
7374
						done();
7375
					}
7376
				} );
7377
	}
7378
} );
7379
7380
function parseClip( str, element ) {
7381
		var outerWidth = element.outerWidth(),
7382
			outerHeight = element.outerHeight(),
7383
			clipRegex = /^rect\((-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto),?\s*(-?\d*\.?\d*px|-?\d+%|auto)\)$/,
7384
			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
7385
7386
		return {
7387
			top: parseFloat( values[ 1 ] ) || 0,
7388
			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
7389
			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
7390
			left: parseFloat( values[ 4 ] ) || 0
7391
		};
7392
}
7393
7394
$.fx.step.clip = function( fx ) {
7395
	if ( !fx.clipInit ) {
7396
		fx.start = $( fx.elem ).cssClip();
7397
		if ( typeof fx.end === "string" ) {
7398
			fx.end = parseClip( fx.end, fx.elem );
7399
		}
7400
		fx.clipInit = true;
7401
	}
7402
7403
	$( fx.elem ).cssClip( {
7404
		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
7405
		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
7406
		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
7407
		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
7408
	} );
7409
};
7410
7411
} )();
7412
7413
/******************************************************************************/
7414
/*********************************** EASING ***********************************/
7415
/******************************************************************************/
7416
7417
( function() {
7418
7419
// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
7420
7421
var baseEasings = {};
7422
7423
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
7424
	baseEasings[ name ] = function( p ) {
7425
		return Math.pow( p, i + 2 );
7426
	};
7427
} );
7428
7429
$.extend( baseEasings, {
7430
	Sine: function( p ) {
7431
		return 1 - Math.cos( p * Math.PI / 2 );
7432
	},
7433
	Circ: function( p ) {
7434
		return 1 - Math.sqrt( 1 - p * p );
7435
	},
7436
	Elastic: function( p ) {
7437
		return p === 0 || p === 1 ? p :
7438
			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
7439
	},
7440
	Back: function( p ) {
7441
		return p * p * ( 3 * p - 2 );
7442
	},
7443
	Bounce: function( p ) {
7444
		var pow2,
7445
			bounce = 4;
7446
7447
		while ( p < ( ( pow2 = Math.pow( 2, --bounce ) ) - 1 ) / 11 ) {}
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...
7448
		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
7449
	}
7450
} );
7451
7452
$.each( baseEasings, function( name, easeIn ) {
7453
	$.easing[ "easeIn" + name ] = easeIn;
7454
	$.easing[ "easeOut" + name ] = function( p ) {
7455
		return 1 - easeIn( 1 - p );
7456
	};
7457
	$.easing[ "easeInOut" + name ] = function( p ) {
7458
		return p < 0.5 ?
7459
			easeIn( p * 2 ) / 2 :
7460
			1 - easeIn( p * -2 + 2 ) / 2;
7461
	};
7462
} );
7463
7464
} )();
7465
7466
var effect = $.effects;
7467
7468
7469
/*!
7470
 * jQuery UI Effects Blind 1.12.0
7471
 * http://jqueryui.com
7472
 *
7473
 * Copyright jQuery Foundation and other contributors
7474
 * Released under the MIT license.
7475
 * http://jquery.org/license
7476
 */
7477
7478
//>>label: Blind Effect
7479
//>>group: Effects
7480
//>>description: Blinds the element.
7481
//>>docs: http://api.jqueryui.com/blind-effect/
7482
//>>demos: http://jqueryui.com/effect/
7483
7484
7485
7486
var effectsEffectBlind = $.effects.define( "blind", "hide", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectBlind seems to be never used. Consider removing it.
Loading history...
7487
	var map = {
7488
			up: [ "bottom", "top" ],
7489
			vertical: [ "bottom", "top" ],
7490
			down: [ "top", "bottom" ],
7491
			left: [ "right", "left" ],
7492
			horizontal: [ "right", "left" ],
7493
			right: [ "left", "right" ]
7494
		},
7495
		element = $( this ),
7496
		direction = options.direction || "up",
7497
		start = element.cssClip(),
7498
		animate = { clip: $.extend( {}, start ) },
7499
		placeholder = $.effects.createPlaceholder( element );
7500
7501
	animate.clip[ map[ direction ][ 0 ] ] = animate.clip[ map[ direction ][ 1 ] ];
7502
7503
	if ( options.mode === "show" ) {
7504
		element.cssClip( animate.clip );
7505
		if ( placeholder ) {
7506
			placeholder.css( $.effects.clipToBox( animate ) );
7507
		}
7508
7509
		animate.clip = start;
7510
	}
7511
7512
	if ( placeholder ) {
7513
		placeholder.animate( $.effects.clipToBox( animate ), options.duration, options.easing );
7514
	}
7515
7516
	element.animate( animate, {
7517
		queue: false,
7518
		duration: options.duration,
7519
		easing: options.easing,
7520
		complete: done
7521
	} );
7522
} );
7523
7524
7525
/*!
7526
 * jQuery UI Effects Bounce 1.12.0
7527
 * http://jqueryui.com
7528
 *
7529
 * Copyright jQuery Foundation and other contributors
7530
 * Released under the MIT license.
7531
 * http://jquery.org/license
7532
 */
7533
7534
//>>label: Bounce Effect
7535
//>>group: Effects
7536
//>>description: Bounces an element horizontally or vertically n times.
7537
//>>docs: http://api.jqueryui.com/bounce-effect/
7538
//>>demos: http://jqueryui.com/effect/
7539
7540
7541
7542
var effectsEffectBounce = $.effects.define( "bounce", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectBounce seems to be never used. Consider removing it.
Loading history...
7543
	var upAnim, downAnim, refValue,
7544
		element = $( this ),
7545
7546
		// Defaults:
7547
		mode = options.mode,
7548
		hide = mode === "hide",
7549
		show = mode === "show",
7550
		direction = options.direction || "up",
7551
		distance = options.distance,
7552
		times = options.times || 5,
7553
7554
		// Number of internal animations
7555
		anims = times * 2 + ( show || hide ? 1 : 0 ),
7556
		speed = options.duration / anims,
7557
		easing = options.easing,
7558
7559
		// Utility:
7560
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
7561
		motion = ( direction === "up" || direction === "left" ),
7562
		i = 0,
7563
7564
		queuelen = element.queue().length;
7565
7566
	$.effects.createPlaceholder( element );
7567
7568
	refValue = element.css( ref );
7569
7570
	// Default distance for the BIGGEST bounce is the outer Distance / 3
7571
	if ( !distance ) {
7572
		distance = element[ ref === "top" ? "outerHeight" : "outerWidth" ]() / 3;
7573
	}
7574
7575
	if ( show ) {
7576
		downAnim = { opacity: 1 };
7577
		downAnim[ ref ] = refValue;
7578
7579
		// If we are showing, force opacity 0 and set the initial position
7580
		// then do the "first" animation
7581
		element
7582
			.css( "opacity", 0 )
7583
			.css( ref, motion ? -distance * 2 : distance * 2 )
7584
			.animate( downAnim, speed, easing );
7585
	}
7586
7587
	// Start at the smallest distance if we are hiding
7588
	if ( hide ) {
7589
		distance = distance / Math.pow( 2, times - 1 );
7590
	}
7591
7592
	downAnim = {};
7593
	downAnim[ ref ] = refValue;
7594
7595
	// Bounces up/down/left/right then back to 0 -- times * 2 animations happen here
7596
	for ( ; i < times; i++ ) {
7597
		upAnim = {};
7598
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
7599
7600
		element
7601
			.animate( upAnim, speed, easing )
7602
			.animate( downAnim, speed, easing );
7603
7604
		distance = hide ? distance * 2 : distance / 2;
7605
	}
7606
7607
	// Last Bounce when Hiding
7608
	if ( hide ) {
7609
		upAnim = { opacity: 0 };
7610
		upAnim[ ref ] = ( motion ? "-=" : "+=" ) + distance;
7611
7612
		element.animate( upAnim, speed, easing );
7613
	}
7614
7615
	element.queue( done );
7616
7617
	$.effects.unshift( element, queuelen, anims + 1 );
7618
} );
7619
7620
7621
/*!
7622
 * jQuery UI Effects Clip 1.12.0
7623
 * http://jqueryui.com
7624
 *
7625
 * Copyright jQuery Foundation and other contributors
7626
 * Released under the MIT license.
7627
 * http://jquery.org/license
7628
 */
7629
7630
//>>label: Clip Effect
7631
//>>group: Effects
7632
//>>description: Clips the element on and off like an old TV.
7633
//>>docs: http://api.jqueryui.com/clip-effect/
7634
//>>demos: http://jqueryui.com/effect/
7635
7636
7637
7638
var effectsEffectClip = $.effects.define( "clip", "hide", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectClip seems to be never used. Consider removing it.
Loading history...
7639
	var start,
7640
		animate = {},
7641
		element = $( this ),
7642
		direction = options.direction || "vertical",
7643
		both = direction === "both",
7644
		horizontal = both || direction === "horizontal",
7645
		vertical = both || direction === "vertical";
7646
7647
	start = element.cssClip();
7648
	animate.clip = {
7649
		top: vertical ? ( start.bottom - start.top ) / 2 : start.top,
7650
		right: horizontal ? ( start.right - start.left ) / 2 : start.right,
7651
		bottom: vertical ? ( start.bottom - start.top ) / 2 : start.bottom,
7652
		left: horizontal ? ( start.right - start.left ) / 2 : start.left
7653
	};
7654
7655
	$.effects.createPlaceholder( element );
7656
7657
	if ( options.mode === "show" ) {
7658
		element.cssClip( animate.clip );
7659
		animate.clip = start;
7660
	}
7661
7662
	element.animate( animate, {
7663
		queue: false,
7664
		duration: options.duration,
7665
		easing: options.easing,
7666
		complete: done
7667
	} );
7668
7669
} );
7670
7671
7672
/*!
7673
 * jQuery UI Effects Drop 1.12.0
7674
 * http://jqueryui.com
7675
 *
7676
 * Copyright jQuery Foundation and other contributors
7677
 * Released under the MIT license.
7678
 * http://jquery.org/license
7679
 */
7680
7681
//>>label: Drop Effect
7682
//>>group: Effects
7683
//>>description: Moves an element in one direction and hides it at the same time.
7684
//>>docs: http://api.jqueryui.com/drop-effect/
7685
//>>demos: http://jqueryui.com/effect/
7686
7687
7688
7689
var effectsEffectDrop = $.effects.define( "drop", "hide", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectDrop seems to be never used. Consider removing it.
Loading history...
7690
7691
	var distance,
7692
		element = $( this ),
7693
		mode = options.mode,
7694
		show = mode === "show",
7695
		direction = options.direction || "left",
7696
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
7697
		motion = ( direction === "up" || direction === "left" ) ? "-=" : "+=",
7698
		oppositeMotion = ( motion === "+=" ) ? "-=" : "+=",
7699
		animation = {
7700
			opacity: 0
7701
		};
7702
7703
	$.effects.createPlaceholder( element );
7704
7705
	distance = options.distance ||
7706
		element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ) / 2;
7707
7708
	animation[ ref ] = motion + distance;
7709
7710
	if ( show ) {
7711
		element.css( animation );
7712
7713
		animation[ ref ] = oppositeMotion + distance;
7714
		animation.opacity = 1;
7715
	}
7716
7717
	// Animate
7718
	element.animate( animation, {
7719
		queue: false,
7720
		duration: options.duration,
7721
		easing: options.easing,
7722
		complete: done
7723
	} );
7724
} );
7725
7726
7727
/*!
7728
 * jQuery UI Effects Explode 1.12.0
7729
 * http://jqueryui.com
7730
 *
7731
 * Copyright jQuery Foundation and other contributors
7732
 * Released under the MIT license.
7733
 * http://jquery.org/license
7734
 */
7735
7736
//>>label: Explode Effect
7737
//>>group: Effects
7738
// jscs:disable maximumLineLength
7739
//>>description: Explodes an element in all directions into n pieces. Implodes an element to its original wholeness.
7740
// jscs:enable maximumLineLength
7741
//>>docs: http://api.jqueryui.com/explode-effect/
7742
//>>demos: http://jqueryui.com/effect/
7743
7744
7745
7746
var effectsEffectExplode = $.effects.define( "explode", "hide", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectExplode seems to be never used. Consider removing it.
Loading history...
7747
7748
	var i, j, left, top, mx, my,
7749
		rows = options.pieces ? Math.round( Math.sqrt( options.pieces ) ) : 3,
7750
		cells = rows,
7751
		element = $( this ),
7752
		mode = options.mode,
7753
		show = mode === "show",
7754
7755
		// Show and then visibility:hidden the element before calculating offset
7756
		offset = element.show().css( "visibility", "hidden" ).offset(),
7757
7758
		// Width and height of a piece
7759
		width = Math.ceil( element.outerWidth() / cells ),
7760
		height = Math.ceil( element.outerHeight() / rows ),
7761
		pieces = [];
7762
7763
	// Children animate complete:
7764
	function childComplete() {
7765
		pieces.push( this );
7766
		if ( pieces.length === rows * cells ) {
7767
			animComplete();
7768
		}
7769
	}
7770
7771
	// Clone the element for each row and cell.
7772
	for ( i = 0; i < rows; i++ ) { // ===>
7773
		top = offset.top + i * height;
7774
		my = i - ( rows - 1 ) / 2;
7775
7776
		for ( j = 0; j < cells; j++ ) { // |||
7777
			left = offset.left + j * width;
7778
			mx = j - ( cells - 1 ) / 2;
7779
7780
			// Create a clone of the now hidden main element that will be absolute positioned
7781
			// within a wrapper div off the -left and -top equal to size of our pieces
7782
			element
7783
				.clone()
7784
				.appendTo( "body" )
7785
				.wrap( "<div></div>" )
7786
				.css( {
7787
					position: "absolute",
7788
					visibility: "visible",
7789
					left: -j * width,
7790
					top: -i * height
7791
				} )
7792
7793
				// Select the wrapper - make it overflow: hidden and absolute positioned based on
7794
				// where the original was located +left and +top equal to the size of pieces
7795
				.parent()
7796
					.addClass( "ui-effects-explode" )
7797
					.css( {
7798
						position: "absolute",
7799
						overflow: "hidden",
7800
						width: width,
7801
						height: height,
7802
						left: left + ( show ? mx * width : 0 ),
7803
						top: top + ( show ? my * height : 0 ),
7804
						opacity: show ? 0 : 1
7805
					} )
7806
					.animate( {
7807
						left: left + ( show ? 0 : mx * width ),
7808
						top: top + ( show ? 0 : my * height ),
7809
						opacity: show ? 1 : 0
7810
					}, options.duration || 500, options.easing, childComplete );
7811
		}
7812
	}
7813
7814
	function animComplete() {
7815
		element.css( {
7816
			visibility: "visible"
7817
		} );
7818
		$( pieces ).remove();
7819
		done();
7820
	}
7821
} );
7822
7823
7824
/*!
7825
 * jQuery UI Effects Fade 1.12.0
7826
 * http://jqueryui.com
7827
 *
7828
 * Copyright jQuery Foundation and other contributors
7829
 * Released under the MIT license.
7830
 * http://jquery.org/license
7831
 */
7832
7833
//>>label: Fade Effect
7834
//>>group: Effects
7835
//>>description: Fades the element.
7836
//>>docs: http://api.jqueryui.com/fade-effect/
7837
//>>demos: http://jqueryui.com/effect/
7838
7839
7840
7841
var effectsEffectFade = $.effects.define( "fade", "toggle", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectFade seems to be never used. Consider removing it.
Loading history...
7842
	var show = options.mode === "show";
7843
7844
	$( this )
7845
		.css( "opacity", show ? 0 : 1 )
7846
		.animate( {
7847
			opacity: show ? 1 : 0
7848
		}, {
7849
			queue: false,
7850
			duration: options.duration,
7851
			easing: options.easing,
7852
			complete: done
7853
		} );
7854
} );
7855
7856
7857
/*!
7858
 * jQuery UI Effects Fold 1.12.0
7859
 * http://jqueryui.com
7860
 *
7861
 * Copyright jQuery Foundation and other contributors
7862
 * Released under the MIT license.
7863
 * http://jquery.org/license
7864
 */
7865
7866
//>>label: Fold Effect
7867
//>>group: Effects
7868
//>>description: Folds an element first horizontally and then vertically.
7869
//>>docs: http://api.jqueryui.com/fold-effect/
7870
//>>demos: http://jqueryui.com/effect/
7871
7872
7873
7874
var effectsEffectFold = $.effects.define( "fold", "hide", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectFold seems to be never used. Consider removing it.
Loading history...
7875
7876
	// Create element
7877
	var element = $( this ),
7878
		mode = options.mode,
7879
		show = mode === "show",
7880
		hide = mode === "hide",
7881
		size = options.size || 15,
7882
		percent = /([0-9]+)%/.exec( size ),
7883
		horizFirst = !!options.horizFirst,
7884
		ref = horizFirst ? [ "right", "bottom" ] : [ "bottom", "right" ],
7885
		duration = options.duration / 2,
7886
7887
		placeholder = $.effects.createPlaceholder( element ),
7888
7889
		start = element.cssClip(),
7890
		animation1 = { clip: $.extend( {}, start ) },
7891
		animation2 = { clip: $.extend( {}, start ) },
7892
7893
		distance = [ start[ ref[ 0 ] ], start[ ref[ 1 ] ] ],
7894
7895
		queuelen = element.queue().length;
7896
7897
	if ( percent ) {
7898
		size = parseInt( percent[ 1 ], 10 ) / 100 * distance[ hide ? 0 : 1 ];
7899
	}
7900
	animation1.clip[ ref[ 0 ] ] = size;
7901
	animation2.clip[ ref[ 0 ] ] = size;
7902
	animation2.clip[ ref[ 1 ] ] = 0;
7903
7904
	if ( show ) {
7905
		element.cssClip( animation2.clip );
7906
		if ( placeholder ) {
7907
			placeholder.css( $.effects.clipToBox( animation2 ) );
7908
		}
7909
7910
		animation2.clip = start;
7911
	}
7912
7913
	// Animate
7914
	element
7915
		.queue( function( next ) {
7916
			if ( placeholder ) {
7917
				placeholder
7918
					.animate( $.effects.clipToBox( animation1 ), duration, options.easing )
7919
					.animate( $.effects.clipToBox( animation2 ), duration, options.easing );
7920
			}
7921
7922
			next();
7923
		} )
7924
		.animate( animation1, duration, options.easing )
7925
		.animate( animation2, duration, options.easing )
7926
		.queue( done );
7927
7928
	$.effects.unshift( element, queuelen, 4 );
7929
} );
7930
7931
7932
/*!
7933
 * jQuery UI Effects Highlight 1.12.0
7934
 * http://jqueryui.com
7935
 *
7936
 * Copyright jQuery Foundation and other contributors
7937
 * Released under the MIT license.
7938
 * http://jquery.org/license
7939
 */
7940
7941
//>>label: Highlight Effect
7942
//>>group: Effects
7943
//>>description: Highlights the background of an element in a defined color for a custom duration.
7944
//>>docs: http://api.jqueryui.com/highlight-effect/
7945
//>>demos: http://jqueryui.com/effect/
7946
7947
7948
7949
var effectsEffectHighlight = $.effects.define( "highlight", "show", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectHighlight seems to be never used. Consider removing it.
Loading history...
7950
	var element = $( this ),
7951
		animation = {
7952
			backgroundColor: element.css( "backgroundColor" )
7953
		};
7954
7955
	if ( options.mode === "hide" ) {
7956
		animation.opacity = 0;
7957
	}
7958
7959
	$.effects.saveStyle( element );
7960
7961
	element
7962
		.css( {
7963
			backgroundImage: "none",
7964
			backgroundColor: options.color || "#ffff99"
7965
		} )
7966
		.animate( animation, {
7967
			queue: false,
7968
			duration: options.duration,
7969
			easing: options.easing,
7970
			complete: done
7971
		} );
7972
} );
7973
7974
7975
/*!
7976
 * jQuery UI Effects Size 1.12.0
7977
 * http://jqueryui.com
7978
 *
7979
 * Copyright jQuery Foundation and other contributors
7980
 * Released under the MIT license.
7981
 * http://jquery.org/license
7982
 */
7983
7984
//>>label: Size Effect
7985
//>>group: Effects
7986
//>>description: Resize an element to a specified width and height.
7987
//>>docs: http://api.jqueryui.com/size-effect/
7988
//>>demos: http://jqueryui.com/effect/
7989
7990
7991
7992
var effectsEffectSize = $.effects.define( "size", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectSize seems to be never used. Consider removing it.
Loading history...
7993
7994
	// Create element
7995
	var baseline, factor, temp,
7996
		element = $( this ),
7997
7998
		// Copy for children
7999
		cProps = [ "fontSize" ],
8000
		vProps = [ "borderTopWidth", "borderBottomWidth", "paddingTop", "paddingBottom" ],
8001
		hProps = [ "borderLeftWidth", "borderRightWidth", "paddingLeft", "paddingRight" ],
8002
8003
		// Set options
8004
		mode = options.mode,
8005
		restore = mode !== "effect",
8006
		scale = options.scale || "both",
8007
		origin = options.origin || [ "middle", "center" ],
8008
		position = element.css( "position" ),
8009
		pos = element.position(),
8010
		original = $.effects.scaledDimensions( element ),
8011
		from = options.from || original,
8012
		to = options.to || $.effects.scaledDimensions( element, 0 );
8013
8014
	$.effects.createPlaceholder( element );
8015
8016
	if ( mode === "show" ) {
8017
		temp = from;
8018
		from = to;
8019
		to = temp;
8020
	}
8021
8022
	// Set scaling factor
8023
	factor = {
8024
		from: {
8025
			y: from.height / original.height,
8026
			x: from.width / original.width
8027
		},
8028
		to: {
8029
			y: to.height / original.height,
8030
			x: to.width / original.width
8031
		}
8032
	};
8033
8034
	// Scale the css box
8035
	if ( scale === "box" || scale === "both" ) {
8036
8037
		// Vertical props scaling
8038
		if ( factor.from.y !== factor.to.y ) {
8039
			from = $.effects.setTransition( element, vProps, factor.from.y, from );
8040
			to = $.effects.setTransition( element, vProps, factor.to.y, to );
8041
		}
8042
8043
		// Horizontal props scaling
8044
		if ( factor.from.x !== factor.to.x ) {
8045
			from = $.effects.setTransition( element, hProps, factor.from.x, from );
8046
			to = $.effects.setTransition( element, hProps, factor.to.x, to );
8047
		}
8048
	}
8049
8050
	// Scale the content
8051
	if ( scale === "content" || scale === "both" ) {
8052
8053
		// Vertical props scaling
8054
		if ( factor.from.y !== factor.to.y ) {
8055
			from = $.effects.setTransition( element, cProps, factor.from.y, from );
8056
			to = $.effects.setTransition( element, cProps, factor.to.y, to );
8057
		}
8058
	}
8059
8060
	// Adjust the position properties based on the provided origin points
8061
	if ( origin ) {
8062
		baseline = $.effects.getBaseline( origin, original );
8063
		from.top = ( original.outerHeight - from.outerHeight ) * baseline.y + pos.top;
8064
		from.left = ( original.outerWidth - from.outerWidth ) * baseline.x + pos.left;
8065
		to.top = ( original.outerHeight - to.outerHeight ) * baseline.y + pos.top;
8066
		to.left = ( original.outerWidth - to.outerWidth ) * baseline.x + pos.left;
8067
	}
8068
	element.css( from );
8069
8070
	// Animate the children if desired
8071
	if ( scale === "content" || scale === "both" ) {
8072
8073
		vProps = vProps.concat( [ "marginTop", "marginBottom" ] ).concat( cProps );
8074
		hProps = hProps.concat( [ "marginLeft", "marginRight" ] );
8075
8076
		// Only animate children with width attributes specified
8077
		// TODO: is this right? should we include anything with css width specified as well
8078
		element.find( "*[width]" ).each( function() {
8079
			var child = $( this ),
8080
				childOriginal = $.effects.scaledDimensions( child ),
8081
				childFrom = {
8082
					height: childOriginal.height * factor.from.y,
8083
					width: childOriginal.width * factor.from.x,
8084
					outerHeight: childOriginal.outerHeight * factor.from.y,
8085
					outerWidth: childOriginal.outerWidth * factor.from.x
8086
				},
8087
				childTo = {
8088
					height: childOriginal.height * factor.to.y,
8089
					width: childOriginal.width * factor.to.x,
8090
					outerHeight: childOriginal.height * factor.to.y,
8091
					outerWidth: childOriginal.width * factor.to.x
8092
				};
8093
8094
			// Vertical props scaling
8095
			if ( factor.from.y !== factor.to.y ) {
8096
				childFrom = $.effects.setTransition( child, vProps, factor.from.y, childFrom );
8097
				childTo = $.effects.setTransition( child, vProps, factor.to.y, childTo );
8098
			}
8099
8100
			// Horizontal props scaling
8101
			if ( factor.from.x !== factor.to.x ) {
8102
				childFrom = $.effects.setTransition( child, hProps, factor.from.x, childFrom );
8103
				childTo = $.effects.setTransition( child, hProps, factor.to.x, childTo );
8104
			}
8105
8106
			if ( restore ) {
8107
				$.effects.saveStyle( child );
8108
			}
8109
8110
			// Animate children
8111
			child.css( childFrom );
8112
			child.animate( childTo, options.duration, options.easing, function() {
8113
8114
				// Restore children
8115
				if ( restore ) {
8116
					$.effects.restoreStyle( child );
8117
				}
8118
			} );
8119
		} );
8120
	}
8121
8122
	// Animate
8123
	element.animate( to, {
8124
		queue: false,
8125
		duration: options.duration,
8126
		easing: options.easing,
8127
		complete: function() {
8128
8129
			var offset = element.offset();
8130
8131
			if ( to.opacity === 0 ) {
8132
				element.css( "opacity", from.opacity );
8133
			}
8134
8135
			if ( !restore ) {
8136
				element
8137
					.css( "position", position === "static" ? "relative" : position )
8138
					.offset( offset );
8139
8140
				// Need to save style here so that automatic style restoration
8141
				// doesn't restore to the original styles from before the animation.
8142
				$.effects.saveStyle( element );
8143
			}
8144
8145
			done();
8146
		}
8147
	} );
8148
8149
} );
8150
8151
8152
/*!
8153
 * jQuery UI Effects Scale 1.12.0
8154
 * http://jqueryui.com
8155
 *
8156
 * Copyright jQuery Foundation and other contributors
8157
 * Released under the MIT license.
8158
 * http://jquery.org/license
8159
 */
8160
8161
//>>label: Scale Effect
8162
//>>group: Effects
8163
//>>description: Grows or shrinks an element and its content.
8164
//>>docs: http://api.jqueryui.com/scale-effect/
8165
//>>demos: http://jqueryui.com/effect/
8166
8167
8168
8169
var effectsEffectScale = $.effects.define( "scale", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectScale seems to be never used. Consider removing it.
Loading history...
8170
8171
	// Create element
8172
	var el = $( this ),
8173
		mode = options.mode,
8174
		percent = parseInt( options.percent, 10 ) ||
8175
			( parseInt( options.percent, 10 ) === 0 ? 0 : ( mode !== "effect" ? 0 : 100 ) ),
8176
8177
		newOptions = $.extend( true, {
8178
			from: $.effects.scaledDimensions( el ),
8179
			to: $.effects.scaledDimensions( el, percent, options.direction || "both" ),
8180
			origin: options.origin || [ "middle", "center" ]
8181
		}, options );
8182
8183
	// Fade option to support puff
8184
	if ( options.fade ) {
8185
		newOptions.from.opacity = 1;
8186
		newOptions.to.opacity = 0;
8187
	}
8188
8189
	$.effects.effect.size.call( this, newOptions, done );
8190
} );
8191
8192
8193
/*!
8194
 * jQuery UI Effects Puff 1.12.0
8195
 * http://jqueryui.com
8196
 *
8197
 * Copyright jQuery Foundation and other contributors
8198
 * Released under the MIT license.
8199
 * http://jquery.org/license
8200
 */
8201
8202
//>>label: Puff Effect
8203
//>>group: Effects
8204
//>>description: Creates a puff effect by scaling the element up and hiding it at the same time.
8205
//>>docs: http://api.jqueryui.com/puff-effect/
8206
//>>demos: http://jqueryui.com/effect/
8207
8208
8209
8210
var effectsEffectPuff = $.effects.define( "puff", "hide", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectPuff seems to be never used. Consider removing it.
Loading history...
8211
	var newOptions = $.extend( true, {}, options, {
8212
		fade: true,
8213
		percent: parseInt( options.percent, 10 ) || 150
8214
	} );
8215
8216
	$.effects.effect.scale.call( this, newOptions, done );
8217
} );
8218
8219
8220
/*!
8221
 * jQuery UI Effects Pulsate 1.12.0
8222
 * http://jqueryui.com
8223
 *
8224
 * Copyright jQuery Foundation and other contributors
8225
 * Released under the MIT license.
8226
 * http://jquery.org/license
8227
 */
8228
8229
//>>label: Pulsate Effect
8230
//>>group: Effects
8231
//>>description: Pulsates an element n times by changing the opacity to zero and back.
8232
//>>docs: http://api.jqueryui.com/pulsate-effect/
8233
//>>demos: http://jqueryui.com/effect/
8234
8235
8236
8237
var effectsEffectPulsate = $.effects.define( "pulsate", "show", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectPulsate seems to be never used. Consider removing it.
Loading history...
8238
	var element = $( this ),
8239
		mode = options.mode,
8240
		show = mode === "show",
8241
		hide = mode === "hide",
8242
		showhide = show || hide,
8243
8244
		// Showing or hiding leaves off the "last" animation
8245
		anims = ( ( options.times || 5 ) * 2 ) + ( showhide ? 1 : 0 ),
8246
		duration = options.duration / anims,
8247
		animateTo = 0,
8248
		i = 1,
8249
		queuelen = element.queue().length;
8250
8251
	if ( show || !element.is( ":visible" ) ) {
8252
		element.css( "opacity", 0 ).show();
8253
		animateTo = 1;
8254
	}
8255
8256
	// Anims - 1 opacity "toggles"
8257
	for ( ; i < anims; i++ ) {
8258
		element.animate( { opacity: animateTo }, duration, options.easing );
8259
		animateTo = 1 - animateTo;
8260
	}
8261
8262
	element.animate( { opacity: animateTo }, duration, options.easing );
8263
8264
	element.queue( done );
8265
8266
	$.effects.unshift( element, queuelen, anims + 1 );
8267
} );
8268
8269
8270
/*!
8271
 * jQuery UI Effects Shake 1.12.0
8272
 * http://jqueryui.com
8273
 *
8274
 * Copyright jQuery Foundation and other contributors
8275
 * Released under the MIT license.
8276
 * http://jquery.org/license
8277
 */
8278
8279
//>>label: Shake Effect
8280
//>>group: Effects
8281
//>>description: Shakes an element horizontally or vertically n times.
8282
//>>docs: http://api.jqueryui.com/shake-effect/
8283
//>>demos: http://jqueryui.com/effect/
8284
8285
8286
8287
var effectsEffectShake = $.effects.define( "shake", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectShake seems to be never used. Consider removing it.
Loading history...
8288
8289
	var i = 1,
8290
		element = $( this ),
8291
		direction = options.direction || "left",
8292
		distance = options.distance || 20,
8293
		times = options.times || 3,
8294
		anims = times * 2 + 1,
8295
		speed = Math.round( options.duration / anims ),
8296
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
8297
		positiveMotion = ( direction === "up" || direction === "left" ),
8298
		animation = {},
8299
		animation1 = {},
8300
		animation2 = {},
8301
8302
		queuelen = element.queue().length;
8303
8304
	$.effects.createPlaceholder( element );
8305
8306
	// Animation
8307
	animation[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance;
8308
	animation1[ ref ] = ( positiveMotion ? "+=" : "-=" ) + distance * 2;
8309
	animation2[ ref ] = ( positiveMotion ? "-=" : "+=" ) + distance * 2;
8310
8311
	// Animate
8312
	element.animate( animation, speed, options.easing );
8313
8314
	// Shakes
8315
	for ( ; i < times; i++ ) {
8316
		element
8317
			.animate( animation1, speed, options.easing )
8318
			.animate( animation2, speed, options.easing );
8319
	}
8320
8321
	element
8322
		.animate( animation1, speed, options.easing )
8323
		.animate( animation, speed / 2, options.easing )
8324
		.queue( done );
8325
8326
	$.effects.unshift( element, queuelen, anims + 1 );
8327
} );
8328
8329
8330
/*!
8331
 * jQuery UI Effects Slide 1.12.0
8332
 * http://jqueryui.com
8333
 *
8334
 * Copyright jQuery Foundation and other contributors
8335
 * Released under the MIT license.
8336
 * http://jquery.org/license
8337
 */
8338
8339
//>>label: Slide Effect
8340
//>>group: Effects
8341
//>>description: Slides an element in and out of the viewport.
8342
//>>docs: http://api.jqueryui.com/slide-effect/
8343
//>>demos: http://jqueryui.com/effect/
8344
8345
8346
8347
var effectsEffectSlide = $.effects.define( "slide", "show", function( options, done ) {
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectSlide seems to be never used. Consider removing it.
Loading history...
8348
	var startClip, startRef,
8349
		element = $( this ),
8350
		map = {
8351
			up: [ "bottom", "top" ],
8352
			down: [ "top", "bottom" ],
8353
			left: [ "right", "left" ],
8354
			right: [ "left", "right" ]
8355
		},
8356
		mode = options.mode,
8357
		direction = options.direction || "left",
8358
		ref = ( direction === "up" || direction === "down" ) ? "top" : "left",
8359
		positiveMotion = ( direction === "up" || direction === "left" ),
8360
		distance = options.distance ||
8361
			element[ ref === "top" ? "outerHeight" : "outerWidth" ]( true ),
8362
		animation = {};
8363
8364
	$.effects.createPlaceholder( element );
8365
8366
	startClip = element.cssClip();
8367
	startRef = element.position()[ ref ];
8368
8369
	// Define hide animation
8370
	animation[ ref ] = ( positiveMotion ? -1 : 1 ) * distance + startRef;
8371
	animation.clip = element.cssClip();
8372
	animation.clip[ map[ direction ][ 1 ] ] = animation.clip[ map[ direction ][ 0 ] ];
8373
8374
	// Reverse the animation if we're showing
8375
	if ( mode === "show" ) {
8376
		element.cssClip( animation.clip );
8377
		element.css( ref, animation[ ref ] );
8378
		animation.clip = startClip;
8379
		animation[ ref ] = startRef;
8380
	}
8381
8382
	// Actually animate
8383
	element.animate( animation, {
8384
		queue: false,
8385
		duration: options.duration,
8386
		easing: options.easing,
8387
		complete: done
8388
	} );
8389
} );
8390
8391
8392
/*!
8393
 * jQuery UI Effects Transfer 1.12.0
8394
 * http://jqueryui.com
8395
 *
8396
 * Copyright jQuery Foundation and other contributors
8397
 * Released under the MIT license.
8398
 * http://jquery.org/license
8399
 */
8400
8401
//>>label: Transfer Effect
8402
//>>group: Effects
8403
//>>description: Displays a transfer effect from one element to another.
8404
//>>docs: http://api.jqueryui.com/transfer-effect/
8405
//>>demos: http://jqueryui.com/effect/
8406
8407
8408
8409
var effect;
0 ignored issues
show
Comprehensibility Naming Best Practice introduced by
The variable effect already seems to be declared on line 7466. Consider using another variable name or omitting the var keyword.

This check looks for variables that are declared in multiple lines. There may be several reasons for this.

In the simplest case the variable name was reused by mistake. This may lead to very hard to locate bugs.

If you want to reuse a variable for another purpose, consider declaring it at or near the top of your function and just assigning to it subsequently so it is always declared.

Loading history...
8410
if ( $.uiBackCompat !== false ) {
8411
	effect = $.effects.define( "transfer", function( options, done ) {
8412
		$( this ).transfer( options, done );
8413
	} );
8414
}
8415
var effectsEffectTransfer = effect;
0 ignored issues
show
Unused Code introduced by
The variable effectsEffectTransfer seems to be never used. Consider removing it.
Loading history...
8416
8417
8418
8419
8420
}));