effect.js ➔ ... ➔ _normalizeArguments   F
last analyzed

Complexity

Conditions 11
Paths 2048

Size

Total Lines 51

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 11
nc 2048
nop 4
dl 0
loc 51
rs 3.6
c 0
b 0
f 0

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

Complexity

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

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

1
/*!
2
 * jQuery UI Effects 1.12.1
3
 * http://jqueryui.com
4
 *
5
 * Copyright jQuery Foundation and other contributors
6
 * Released under the MIT license.
7
 * http://jquery.org/license
8
 */
9
10
//>>label: Effects Core
11
//>>group: Effects
12
// jscs:disable maximumLineLength
13
//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
14
// jscs:enable maximumLineLength
15
//>>docs: http://api.jqueryui.com/category/effects-core/
16
//>>demos: http://jqueryui.com/effect/
17
18
( function( factory ) {
19
	if ( typeof define === "function" && define.amd ) {
20
21
		// AMD. Register as an anonymous module.
22
		define( [ "jquery", "./version" ], factory );
23
	} else {
24
25
		// Browser globals
26
		factory( jQuery );
27
	}
28
}( function( $ ) {
29
30
var dataSpace = "ui-effects-",
31
	dataSpaceStyle = "ui-effects-style",
32
	dataSpaceAnimated = "ui-effects-animated",
33
34
	// Create a local jQuery because jQuery Color relies on it and the
35
	// global may not exist with AMD and a custom build (#10199)
36
	jQuery = $;
37
38
$.effects = {
39
	effect: {}
40
};
41
42
/*!
43
 * jQuery Color Animations v2.1.2
44
 * https://github.com/jquery/jquery-color
45
 *
46
 * Copyright 2014 jQuery Foundation and other contributors
47
 * Released under the MIT license.
48
 * http://jquery.org/license
49
 *
50
 * Date: Wed Jan 16 08:47:09 2013 -0600
51
 */
52
( function( jQuery, undefined ) {
53
54
	var stepHooks = "backgroundColor borderBottomColor borderLeftColor borderRightColor " +
55
		"borderTopColor color columnRuleColor outlineColor textDecorationColor textEmphasisColor",
56
57
	// Plusequals test for += 100 -= 100
58
	rplusequals = /^([\-+])=\s*(\d+\.?\d*)/,
59
60
	// A set of RE's that can match strings and generate color tuples.
61
	stringParsers = [ {
62
			re: /rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
63
			parse: function( execResult ) {
64
				return [
65
					execResult[ 1 ],
66
					execResult[ 2 ],
67
					execResult[ 3 ],
68
					execResult[ 4 ]
69
				];
70
			}
71
		}, {
72
			re: /rgba?\(\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
73
			parse: function( execResult ) {
74
				return [
75
					execResult[ 1 ] * 2.55,
76
					execResult[ 2 ] * 2.55,
77
					execResult[ 3 ] * 2.55,
78
					execResult[ 4 ]
79
				];
80
			}
81
		}, {
82
83
			// This regex ignores A-F because it's compared against an already lowercased string
84
			re: /#([a-f0-9]{2})([a-f0-9]{2})([a-f0-9]{2})/,
85
			parse: function( execResult ) {
86
				return [
87
					parseInt( execResult[ 1 ], 16 ),
88
					parseInt( execResult[ 2 ], 16 ),
89
					parseInt( execResult[ 3 ], 16 )
90
				];
91
			}
92
		}, {
93
94
			// This regex ignores A-F because it's compared against an already lowercased string
95
			re: /#([a-f0-9])([a-f0-9])([a-f0-9])/,
96
			parse: function( execResult ) {
97
				return [
98
					parseInt( execResult[ 1 ] + execResult[ 1 ], 16 ),
99
					parseInt( execResult[ 2 ] + execResult[ 2 ], 16 ),
100
					parseInt( execResult[ 3 ] + execResult[ 3 ], 16 )
101
				];
102
			}
103
		}, {
104
			re: /hsla?\(\s*(\d+(?:\.\d+)?)\s*,\s*(\d+(?:\.\d+)?)\%\s*,\s*(\d+(?:\.\d+)?)\%\s*(?:,\s*(\d?(?:\.\d+)?)\s*)?\)/,
105
			space: "hsla",
106
			parse: function( execResult ) {
107
				return [
108
					execResult[ 1 ],
109
					execResult[ 2 ] / 100,
110
					execResult[ 3 ] / 100,
111
					execResult[ 4 ]
112
				];
113
			}
114
		} ],
115
116
	// JQuery.Color( )
117
	color = jQuery.Color = function( color, green, blue, alpha ) {
118
		return new jQuery.Color.fn.parse( color, green, blue, alpha );
119
	},
120
	spaces = {
121
		rgba: {
122
			props: {
123
				red: {
124
					idx: 0,
125
					type: "byte"
126
				},
127
				green: {
128
					idx: 1,
129
					type: "byte"
130
				},
131
				blue: {
132
					idx: 2,
133
					type: "byte"
134
				}
135
			}
136
		},
137
138
		hsla: {
139
			props: {
140
				hue: {
141
					idx: 0,
142
					type: "degrees"
143
				},
144
				saturation: {
145
					idx: 1,
146
					type: "percent"
147
				},
148
				lightness: {
149
					idx: 2,
150
					type: "percent"
151
				}
152
			}
153
		}
154
	},
155
	propTypes = {
156
		"byte": {
157
			floor: true,
158
			max: 255
159
		},
160
		"percent": {
161
			max: 1
162
		},
163
		"degrees": {
164
			mod: 360,
165
			floor: true
166
		}
167
	},
168
	support = color.support = {},
169
170
	// Element for support tests
171
	supportElem = jQuery( "<p>" )[ 0 ],
172
173
	// Colors = jQuery.Color.names
174
	colors,
175
176
	// Local aliases of functions called often
177
	each = jQuery.each;
178
179
// Determine rgba support immediately
180
supportElem.style.cssText = "background-color:rgba(1,1,1,.5)";
181
support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1;
182
183
// Define cache name and alpha properties
184
// for rgba and hsla spaces
185
each( spaces, function( spaceName, space ) {
186
	space.cache = "_" + spaceName;
187
	space.props.alpha = {
188
		idx: 3,
189
		type: "percent",
190
		def: 1
191
	};
192
} );
193
194
function clamp( value, prop, allowEmpty ) {
195
	var type = propTypes[ prop.type ] || {};
196
197
	if ( value == null ) {
198
		return ( allowEmpty || !prop.def ) ? null : prop.def;
199
	}
200
201
	// ~~ is an short way of doing floor for positive numbers
202
	value = type.floor ? ~~value : parseFloat( value );
203
204
	// IE will pass in empty strings as value for alpha,
205
	// which will hit this case
206
	if ( isNaN( value ) ) {
207
		return prop.def;
208
	}
209
210
	if ( type.mod ) {
211
212
		// We add mod before modding to make sure that negatives values
213
		// get converted properly: -10 -> 350
214
		return ( value + type.mod ) % type.mod;
215
	}
216
217
	// For now all property types without mod have min and max
218
	return 0 > value ? 0 : type.max < value ? type.max : value;
219
}
220
221
function stringParse( string ) {
222
	var inst = color(),
223
		rgba = inst._rgba = [];
224
225
	string = string.toLowerCase();
226
227
	each( stringParsers, function( i, parser ) {
228
		var parsed,
229
			match = parser.re.exec( string ),
230
			values = match && parser.parse( match ),
231
			spaceName = parser.space || "rgba";
232
233
		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...
234
			parsed = inst[ spaceName ]( values );
235
236
			// If this was an rgba parse the assignment might happen twice
237
			// oh well....
238
			inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ];
239
			rgba = inst._rgba = parsed._rgba;
240
241
			// Exit each( stringParsers ) here because we matched
242
			return false;
243
		}
244
	} );
245
246
	// Found a stringParser that handled it
247
	if ( rgba.length ) {
248
249
		// If this came from a parsed string, force "transparent" when alpha is 0
250
		// chrome, (and maybe others) return "transparent" as rgba(0,0,0,0)
251
		if ( rgba.join() === "0,0,0,0" ) {
252
			jQuery.extend( rgba, colors.transparent );
253
		}
254
		return inst;
255
	}
256
257
	// Named colors
258
	return colors[ string ];
259
}
260
261
color.fn = jQuery.extend( color.prototype, {
262
	parse: function( red, green, blue, alpha ) {
263
		if ( red === undefined ) {
264
			this._rgba = [ null, null, null, null ];
265
			return this;
266
		}
267
		if ( red.jquery || red.nodeType ) {
268
			red = jQuery( red ).css( green );
269
			green = undefined;
270
		}
271
272
		var inst = this,
273
			type = jQuery.type( red ),
274
			rgba = this._rgba = [];
275
276
		// More than 1 argument specified - assume ( red, green, blue, alpha )
277
		if ( green !== undefined ) {
278
			red = [ red, green, blue, alpha ];
279
			type = "array";
280
		}
281
282
		if ( type === "string" ) {
283
			return this.parse( stringParse( red ) || colors._default );
284
		}
285
286
		if ( type === "array" ) {
287
			each( spaces.rgba.props, function( key, prop ) {
288
				rgba[ prop.idx ] = clamp( red[ prop.idx ], prop );
289
			} );
290
			return this;
291
		}
292
293
		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...
294
			if ( red instanceof color ) {
295
				each( spaces, function( spaceName, space ) {
296
					if ( red[ space.cache ] ) {
297
						inst[ space.cache ] = red[ space.cache ].slice();
298
					}
299
				} );
300
			} else {
301
				each( spaces, function( spaceName, space ) {
302
					var cache = space.cache;
303
					each( space.props, function( key, prop ) {
304
305
						// If the cache doesn't exist, and we know how to convert
306
						if ( !inst[ cache ] && space.to ) {
307
308
							// If the value was null, we don't need to copy it
309
							// if the key was alpha, we don't need to copy it either
310
							if ( key === "alpha" || red[ key ] == null ) {
311
								return;
312
							}
313
							inst[ cache ] = space.to( inst._rgba );
314
						}
315
316
						// This is the only case where we allow nulls for ALL properties.
317
						// call clamp with alwaysAllowEmpty
318
						inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true );
319
					} );
320
321
					// Everything defined but alpha?
322
					if ( inst[ cache ] &&
323
							jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) {
324
325
						// Use the default of 1
326
						inst[ cache ][ 3 ] = 1;
327
						if ( space.from ) {
328
							inst._rgba = space.from( inst[ cache ] );
329
						}
330
					}
331
				} );
332
			}
333
			return this;
334
		}
335
	},
336
	is: function( compare ) {
337
		var is = color( compare ),
338
			same = true,
339
			inst = this;
340
341
		each( spaces, function( _, space ) {
342
			var localCache,
343
				isCache = is[ space.cache ];
344
			if ( isCache ) {
345
				localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || [];
346
				each( space.props, function( _, prop ) {
347
					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...
348
						same = ( isCache[ prop.idx ] === localCache[ prop.idx ] );
349
						return same;
350
					}
351
				} );
352
			}
353
			return same;
354
		} );
355
		return same;
356
	},
357
	_space: function() {
358
		var used = [],
359
			inst = this;
360
		each( spaces, function( spaceName, space ) {
361
			if ( inst[ space.cache ] ) {
362
				used.push( spaceName );
363
			}
364
		} );
365
		return used.pop();
366
	},
367
	transition: function( other, distance ) {
368
		var end = color( other ),
369
			spaceName = end._space(),
370
			space = spaces[ spaceName ],
371
			startColor = this.alpha() === 0 ? color( "transparent" ) : this,
372
			start = startColor[ space.cache ] || space.to( startColor._rgba ),
373
			result = start.slice();
374
375
		end = end[ space.cache ];
376
		each( space.props, function( key, prop ) {
377
			var index = prop.idx,
378
				startValue = start[ index ],
379
				endValue = end[ index ],
380
				type = propTypes[ prop.type ] || {};
381
382
			// If null, don't override start value
383
			if ( endValue === null ) {
384
				return;
385
			}
386
387
			// If null - use end
388
			if ( startValue === null ) {
389
				result[ index ] = endValue;
390
			} else {
391
				if ( type.mod ) {
392
					if ( endValue - startValue > type.mod / 2 ) {
393
						startValue += type.mod;
394
					} else if ( startValue - endValue > type.mod / 2 ) {
395
						startValue -= type.mod;
396
					}
397
				}
398
				result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop );
399
			}
400
		} );
401
		return this[ spaceName ]( result );
402
	},
403
	blend: function( opaque ) {
404
405
		// If we are already opaque - return ourself
406
		if ( this._rgba[ 3 ] === 1 ) {
407
			return this;
408
		}
409
410
		var rgb = this._rgba.slice(),
411
			a = rgb.pop(),
412
			blend = color( opaque )._rgba;
413
414
		return color( jQuery.map( rgb, function( v, i ) {
415
			return ( 1 - a ) * blend[ i ] + a * v;
416
		} ) );
417
	},
418
	toRgbaString: function() {
419
		var prefix = "rgba(",
420
			rgba = jQuery.map( this._rgba, function( v, i ) {
421
				return v == null ? ( i > 2 ? 1 : 0 ) : v;
422
			} );
423
424
		if ( rgba[ 3 ] === 1 ) {
425
			rgba.pop();
426
			prefix = "rgb(";
427
		}
428
429
		return prefix + rgba.join() + ")";
430
	},
431
	toHslaString: function() {
432
		var prefix = "hsla(",
433
			hsla = jQuery.map( this.hsla(), function( v, i ) {
434
				if ( v == null ) {
435
					v = i > 2 ? 1 : 0;
436
				}
437
438
				// Catch 1 and 2
439
				if ( i && i < 3 ) {
440
					v = Math.round( v * 100 ) + "%";
441
				}
442
				return v;
443
			} );
444
445
		if ( hsla[ 3 ] === 1 ) {
446
			hsla.pop();
447
			prefix = "hsl(";
448
		}
449
		return prefix + hsla.join() + ")";
450
	},
451
	toHexString: function( includeAlpha ) {
452
		var rgba = this._rgba.slice(),
453
			alpha = rgba.pop();
454
455
		if ( includeAlpha ) {
456
			rgba.push( ~~( alpha * 255 ) );
457
		}
458
459
		return "#" + jQuery.map( rgba, function( v ) {
460
461
			// Default to 0 when nulls exist
462
			v = ( v || 0 ).toString( 16 );
463
			return v.length === 1 ? "0" + v : v;
464
		} ).join( "" );
465
	},
466
	toString: function() {
467
		return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString();
468
	}
469
} );
470
color.fn.parse.prototype = color.fn;
471
472
// Hsla conversions adapted from:
473
// https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021
474
475
function hue2rgb( p, q, h ) {
476
	h = ( h + 1 ) % 1;
477
	if ( h * 6 < 1 ) {
478
		return p + ( q - p ) * h * 6;
479
	}
480
	if ( h * 2 < 1 ) {
481
		return q;
482
	}
483
	if ( h * 3 < 2 ) {
484
		return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6;
485
	}
486
	return p;
487
}
488
489
spaces.hsla.to = function( rgba ) {
490
	if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) {
491
		return [ null, null, null, rgba[ 3 ] ];
492
	}
493
	var r = rgba[ 0 ] / 255,
494
		g = rgba[ 1 ] / 255,
495
		b = rgba[ 2 ] / 255,
496
		a = rgba[ 3 ],
497
		max = Math.max( r, g, b ),
498
		min = Math.min( r, g, b ),
499
		diff = max - min,
500
		add = max + min,
501
		l = add * 0.5,
502
		h, s;
503
504
	if ( min === max ) {
505
		h = 0;
506
	} else if ( r === max ) {
507
		h = ( 60 * ( g - b ) / diff ) + 360;
508
	} else if ( g === max ) {
509
		h = ( 60 * ( b - r ) / diff ) + 120;
510
	} else {
511
		h = ( 60 * ( r - g ) / diff ) + 240;
512
	}
513
514
	// Chroma (diff) == 0 means greyscale which, by definition, saturation = 0%
515
	// otherwise, saturation is based on the ratio of chroma (diff) to lightness (add)
516
	if ( diff === 0 ) {
517
		s = 0;
518
	} else if ( l <= 0.5 ) {
519
		s = diff / add;
520
	} else {
521
		s = diff / ( 2 - add );
522
	}
523
	return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ];
524
};
525
526
spaces.hsla.from = function( hsla ) {
527
	if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) {
528
		return [ null, null, null, hsla[ 3 ] ];
529
	}
530
	var h = hsla[ 0 ] / 360,
531
		s = hsla[ 1 ],
532
		l = hsla[ 2 ],
533
		a = hsla[ 3 ],
534
		q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s,
535
		p = 2 * l - q;
536
537
	return [
538
		Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ),
539
		Math.round( hue2rgb( p, q, h ) * 255 ),
540
		Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ),
541
		a
542
	];
543
};
544
545
each( spaces, function( spaceName, space ) {
546
	var props = space.props,
547
		cache = space.cache,
548
		to = space.to,
549
		from = space.from;
550
551
	// Makes rgba() and hsla()
552
	color.fn[ spaceName ] = function( value ) {
553
554
		// Generate a cache for this space if it doesn't exist
555
		if ( to && !this[ cache ] ) {
556
			this[ cache ] = to( this._rgba );
557
		}
558
		if ( value === undefined ) {
559
			return this[ cache ].slice();
560
		}
561
562
		var ret,
563
			type = jQuery.type( value ),
564
			arr = ( type === "array" || type === "object" ) ? value : arguments,
565
			local = this[ cache ].slice();
566
567
		each( props, function( key, prop ) {
568
			var val = arr[ type === "object" ? key : prop.idx ];
569
			if ( val == null ) {
570
				val = local[ prop.idx ];
571
			}
572
			local[ prop.idx ] = clamp( val, prop );
573
		} );
574
575
		if ( from ) {
576
			ret = color( from( local ) );
577
			ret[ cache ] = local;
578
			return ret;
579
		} else {
580
			return color( local );
581
		}
582
	};
583
584
	// Makes red() green() blue() alpha() hue() saturation() lightness()
585
	each( props, function( key, prop ) {
586
587
		// Alpha is included in more than one space
588
		if ( color.fn[ key ] ) {
589
			return;
590
		}
591
		color.fn[ key ] = function( value ) {
592
			var vtype = jQuery.type( value ),
593
				fn = ( key === "alpha" ? ( this._hsla ? "hsla" : "rgba" ) : spaceName ),
594
				local = this[ fn ](),
595
				cur = local[ prop.idx ],
596
				match;
597
598
			if ( vtype === "undefined" ) {
599
				return cur;
600
			}
601
602
			if ( vtype === "function" ) {
603
				value = value.call( this, cur );
604
				vtype = jQuery.type( value );
605
			}
606
			if ( value == null && prop.empty ) {
607
				return this;
608
			}
609
			if ( vtype === "string" ) {
610
				match = rplusequals.exec( value );
611
				if ( match ) {
612
					value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 );
613
				}
614
			}
615
			local[ prop.idx ] = value;
616
			return this[ fn ]( local );
617
		};
618
	} );
619
} );
620
621
// Add cssHook and .fx.step function for each named hook.
622
// accept a space separated string of properties
623
color.hook = function( hook ) {
624
	var hooks = hook.split( " " );
625
	each( hooks, function( i, hook ) {
626
		jQuery.cssHooks[ hook ] = {
627
			set: function( elem, value ) {
628
				var parsed, curElem,
629
					backgroundColor = "";
630
631
				if ( value !== "transparent" && ( jQuery.type( value ) !== "string" ||
632
						( parsed = stringParse( value ) ) ) ) {
633
					value = color( parsed || value );
634
					if ( !support.rgba && value._rgba[ 3 ] !== 1 ) {
635
						curElem = hook === "backgroundColor" ? elem.parentNode : elem;
636
						while (
637
							( backgroundColor === "" || backgroundColor === "transparent" ) &&
638
							curElem && curElem.style
639
						) {
640
							try {
641
								backgroundColor = jQuery.css( curElem, "backgroundColor" );
642
								curElem = curElem.parentNode;
643
							} catch ( e ) {
644
							}
645
						}
646
647
						value = value.blend( backgroundColor && backgroundColor !== "transparent" ?
648
							backgroundColor :
649
							"_default" );
650
					}
651
652
					value = value.toRgbaString();
653
				}
654
				try {
655
					elem.style[ hook ] = value;
656
				} catch ( e ) {
657
658
					// Wrapped to prevent IE from throwing errors on "invalid" values like
659
					// 'auto' or 'inherit'
660
				}
661
			}
662
		};
663
		jQuery.fx.step[ hook ] = function( fx ) {
664
			if ( !fx.colorInit ) {
665
				fx.start = color( fx.elem, hook );
666
				fx.end = color( fx.end );
667
				fx.colorInit = true;
668
			}
669
			jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) );
670
		};
671
	} );
672
673
};
674
675
color.hook( stepHooks );
676
677
jQuery.cssHooks.borderColor = {
678
	expand: function( value ) {
679
		var expanded = {};
680
681
		each( [ "Top", "Right", "Bottom", "Left" ], function( i, part ) {
682
			expanded[ "border" + part + "Color" ] = value;
683
		} );
684
		return expanded;
685
	}
686
};
687
688
// Basic color names only.
689
// Usage of any of the other color names requires adding yourself or including
690
// jquery.color.svg-names.js.
691
colors = jQuery.Color.names = {
692
693
	// 4.1. Basic color keywords
694
	aqua: "#00ffff",
695
	black: "#000000",
696
	blue: "#0000ff",
697
	fuchsia: "#ff00ff",
698
	gray: "#808080",
699
	green: "#008000",
700
	lime: "#00ff00",
701
	maroon: "#800000",
702
	navy: "#000080",
703
	olive: "#808000",
704
	purple: "#800080",
705
	red: "#ff0000",
706
	silver: "#c0c0c0",
707
	teal: "#008080",
708
	white: "#ffffff",
709
	yellow: "#ffff00",
710
711
	// 4.2.3. "transparent" color keyword
712
	transparent: [ null, null, null, 0 ],
713
714
	_default: "#ffffff"
715
};
716
717
} )( jQuery );
718
719
/******************************************************************************/
720
/****************************** CLASS ANIMATIONS ******************************/
721
/******************************************************************************/
722
( function() {
723
724
var classAnimationActions = [ "add", "remove", "toggle" ],
725
	shorthandStyles = {
726
		border: 1,
727
		borderBottom: 1,
728
		borderColor: 1,
729
		borderLeft: 1,
730
		borderRight: 1,
731
		borderTop: 1,
732
		borderWidth: 1,
733
		margin: 1,
734
		padding: 1
735
	};
736
737
$.each(
738
	[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
739
	function( _, prop ) {
740
		$.fx.step[ prop ] = function( fx ) {
741
			if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
742
				jQuery.style( fx.elem, prop, fx.end );
743
				fx.setAttr = true;
744
			}
745
		};
746
	}
747
);
748
749
function getElementStyles( elem ) {
750
	var key, len,
751
		style = elem.ownerDocument.defaultView ?
752
			elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
753
			elem.currentStyle,
754
		styles = {};
755
756
	if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
757
		len = style.length;
758
		while ( len-- ) {
759
			key = style[ len ];
760
			if ( typeof style[ key ] === "string" ) {
761
				styles[ $.camelCase( key ) ] = style[ key ];
762
			}
763
		}
764
765
	// Support: Opera, IE <9
766
	} else {
767
		for ( key in style ) {
768
			if ( typeof style[ key ] === "string" ) {
769
				styles[ key ] = style[ key ];
770
			}
771
		}
772
	}
773
774
	return styles;
775
}
776
777
function styleDifference( oldStyle, newStyle ) {
778
	var diff = {},
779
		name, value;
780
781
	for ( name in newStyle ) {
782
		value = newStyle[ name ];
783
		if ( oldStyle[ name ] !== value ) {
784
			if ( !shorthandStyles[ name ] ) {
785
				if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
786
					diff[ name ] = value;
787
				}
788
			}
789
		}
790
	}
791
792
	return diff;
793
}
794
795
// Support: jQuery <1.8
796
if ( !$.fn.addBack ) {
797
	$.fn.addBack = function( selector ) {
798
		return this.add( selector == null ?
799
			this.prevObject : this.prevObject.filter( selector )
800
		);
801
	};
802
}
803
804
$.effects.animateClass = function( value, duration, easing, callback ) {
805
	var o = $.speed( duration, easing, callback );
806
807
	return this.queue( function() {
808
		var animated = $( this ),
809
			baseClass = animated.attr( "class" ) || "",
810
			applyClassChange,
811
			allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
812
813
		// Map the animated objects to store the original styles.
814
		allAnimations = allAnimations.map( function() {
815
			var el = $( this );
816
			return {
817
				el: el,
818
				start: getElementStyles( this )
819
			};
820
		} );
821
822
		// Apply class change
823
		applyClassChange = function() {
824
			$.each( classAnimationActions, function( i, action ) {
825
				if ( value[ action ] ) {
826
					animated[ action + "Class" ]( value[ action ] );
827
				}
828
			} );
829
		};
830
		applyClassChange();
831
832
		// Map all animated objects again - calculate new styles and diff
833
		allAnimations = allAnimations.map( function() {
834
			this.end = getElementStyles( this.el[ 0 ] );
835
			this.diff = styleDifference( this.start, this.end );
836
			return this;
837
		} );
838
839
		// Apply original class
840
		animated.attr( "class", baseClass );
841
842
		// Map all animated objects again - this time collecting a promise
843
		allAnimations = allAnimations.map( function() {
844
			var styleInfo = this,
845
				dfd = $.Deferred(),
846
				opts = $.extend( {}, o, {
847
					queue: false,
848
					complete: function() {
849
						dfd.resolve( styleInfo );
850
					}
851
				} );
852
853
			this.el.animate( this.diff, opts );
854
			return dfd.promise();
855
		} );
856
857
		// Once all animations have completed:
858
		$.when.apply( $, allAnimations.get() ).done( function() {
859
860
			// Set the final class
861
			applyClassChange();
862
863
			// For each animated element,
864
			// clear all css properties that were animated
865
			$.each( arguments, function() {
866
				var el = this.el;
867
				$.each( this.diff, function( key ) {
868
					el.css( key, "" );
869
				} );
870
			} );
871
872
			// This is guarnteed to be there if you use jQuery.speed()
873
			// it also handles dequeuing the next anim...
874
			o.complete.call( animated[ 0 ] );
875
		} );
876
	} );
877
};
878
879
$.fn.extend( {
880
	addClass: ( function( orig ) {
881
		return function( classNames, speed, easing, callback ) {
882
			return speed ?
883
				$.effects.animateClass.call( this,
884
					{ add: classNames }, speed, easing, callback ) :
885
				orig.apply( this, arguments );
886
		};
887
	} )( $.fn.addClass ),
888
889
	removeClass: ( function( orig ) {
890
		return function( classNames, speed, easing, callback ) {
891
			return arguments.length > 1 ?
892
				$.effects.animateClass.call( this,
893
					{ remove: classNames }, speed, easing, callback ) :
894
				orig.apply( this, arguments );
895
		};
896
	} )( $.fn.removeClass ),
897
898
	toggleClass: ( function( orig ) {
899
		return function( classNames, force, speed, easing, callback ) {
900
			if ( typeof force === "boolean" || force === undefined ) {
901
				if ( !speed ) {
902
903
					// Without speed parameter
904
					return orig.apply( this, arguments );
905
				} else {
906
					return $.effects.animateClass.call( this,
907
						( force ? { add: classNames } : { remove: classNames } ),
908
						speed, easing, callback );
909
				}
910
			} else {
911
912
				// Without force parameter
913
				return $.effects.animateClass.call( this,
914
					{ toggle: classNames }, force, speed, easing );
915
			}
916
		};
917
	} )( $.fn.toggleClass ),
918
919
	switchClass: function( remove, add, speed, easing, callback ) {
920
		return $.effects.animateClass.call( this, {
921
			add: add,
922
			remove: remove
923
		}, speed, easing, callback );
924
	}
925
} );
926
927
} )();
928
929
/******************************************************************************/
930
/*********************************** EFFECTS **********************************/
931
/******************************************************************************/
932
933
( function() {
934
935
if ( $.expr && $.expr.filters && $.expr.filters.animated ) {
936
	$.expr.filters.animated = ( function( orig ) {
937
		return function( elem ) {
938
			return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
939
		};
940
	} )( $.expr.filters.animated );
941
}
942
943
if ( $.uiBackCompat !== false ) {
944
	$.extend( $.effects, {
945
946
		// Saves a set of properties in a data storage
947
		save: function( element, set ) {
948
			var i = 0, length = set.length;
949
			for ( ; i < length; i++ ) {
950
				if ( set[ i ] !== null ) {
951
					element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
952
				}
953
			}
954
		},
955
956
		// Restores a set of previously saved properties from a data storage
957
		restore: function( element, set ) {
958
			var val, i = 0, length = set.length;
959
			for ( ; i < length; i++ ) {
960
				if ( set[ i ] !== null ) {
961
					val = element.data( dataSpace + set[ i ] );
962
					element.css( set[ i ], val );
963
				}
964
			}
965
		},
966
967
		setMode: function( el, mode ) {
968
			if ( mode === "toggle" ) {
969
				mode = el.is( ":hidden" ) ? "show" : "hide";
970
			}
971
			return mode;
972
		},
973
974
		// Wraps the element around a wrapper that copies position properties
975
		createWrapper: function( element ) {
976
977
			// If the element is already wrapped, return it
978
			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
979
				return element.parent();
980
			}
981
982
			// Wrap the element
983
			var props = {
984
					width: element.outerWidth( true ),
985
					height: element.outerHeight( true ),
986
					"float": element.css( "float" )
987
				},
988
				wrapper = $( "<div></div>" )
989
					.addClass( "ui-effects-wrapper" )
990
					.css( {
991
						fontSize: "100%",
992
						background: "transparent",
993
						border: "none",
994
						margin: 0,
995
						padding: 0
996
					} ),
997
998
				// Store the size in case width/height are defined in % - Fixes #5245
999
				size = {
1000
					width: element.width(),
1001
					height: element.height()
1002
				},
1003
				active = document.activeElement;
1004
1005
			// Support: Firefox
1006
			// Firefox incorrectly exposes anonymous content
1007
			// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
1008
			try {
1009
				active.id;
0 ignored issues
show
introduced by
The result of the property access to active.id is not used.
Loading history...
1010
			} catch ( e ) {
1011
				active = document.body;
1012
			}
1013
1014
			element.wrap( wrapper );
1015
1016
			// Fixes #7595 - Elements lose focus when wrapped.
1017
			if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
1018
				$( active ).trigger( "focus" );
1019
			}
1020
1021
			// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
1022
			// lose the reference to the wrapped element
1023
			wrapper = element.parent();
1024
1025
			// Transfer positioning properties to the wrapper
1026
			if ( element.css( "position" ) === "static" ) {
1027
				wrapper.css( { position: "relative" } );
1028
				element.css( { position: "relative" } );
1029
			} else {
1030
				$.extend( props, {
1031
					position: element.css( "position" ),
1032
					zIndex: element.css( "z-index" )
1033
				} );
1034
				$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
1035
					props[ pos ] = element.css( pos );
1036
					if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
1037
						props[ pos ] = "auto";
1038
					}
1039
				} );
1040
				element.css( {
1041
					position: "relative",
1042
					top: 0,
1043
					left: 0,
1044
					right: "auto",
1045
					bottom: "auto"
1046
				} );
1047
			}
1048
			element.css( size );
1049
1050
			return wrapper.css( props ).show();
1051
		},
1052
1053
		removeWrapper: function( element ) {
1054
			var active = document.activeElement;
1055
1056
			if ( element.parent().is( ".ui-effects-wrapper" ) ) {
1057
				element.parent().replaceWith( element );
1058
1059
				// Fixes #7595 - Elements lose focus when wrapped.
1060
				if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
1061
					$( active ).trigger( "focus" );
1062
				}
1063
			}
1064
1065
			return element;
1066
		}
1067
	} );
1068
}
1069
1070
$.extend( $.effects, {
1071
	version: "1.12.1",
1072
1073
	define: function( name, mode, effect ) {
1074
		if ( !effect ) {
1075
			effect = mode;
1076
			mode = "effect";
1077
		}
1078
1079
		$.effects.effect[ name ] = effect;
1080
		$.effects.effect[ name ].mode = mode;
1081
1082
		return effect;
1083
	},
1084
1085
	scaledDimensions: function( element, percent, direction ) {
1086
		if ( percent === 0 ) {
1087
			return {
1088
				height: 0,
1089
				width: 0,
1090
				outerHeight: 0,
1091
				outerWidth: 0
1092
			};
1093
		}
1094
1095
		var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
1096
			y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
1097
1098
		return {
1099
			height: element.height() * y,
1100
			width: element.width() * x,
1101
			outerHeight: element.outerHeight() * y,
1102
			outerWidth: element.outerWidth() * x
1103
		};
1104
1105
	},
1106
1107
	clipToBox: function( animation ) {
1108
		return {
1109
			width: animation.clip.right - animation.clip.left,
1110
			height: animation.clip.bottom - animation.clip.top,
1111
			left: animation.clip.left,
1112
			top: animation.clip.top
1113
		};
1114
	},
1115
1116
	// Injects recently queued functions to be first in line (after "inprogress")
1117
	unshift: function( element, queueLength, count ) {
1118
		var queue = element.queue();
1119
1120
		if ( queueLength > 1 ) {
1121
			queue.splice.apply( queue,
1122
				[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
1123
		}
1124
		element.dequeue();
1125
	},
1126
1127
	saveStyle: function( element ) {
1128
		element.data( dataSpaceStyle, element[ 0 ].style.cssText );
1129
	},
1130
1131
	restoreStyle: function( element ) {
1132
		element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
1133
		element.removeData( dataSpaceStyle );
1134
	},
1135
1136
	mode: function( element, mode ) {
1137
		var hidden = element.is( ":hidden" );
1138
1139
		if ( mode === "toggle" ) {
1140
			mode = hidden ? "show" : "hide";
1141
		}
1142
		if ( hidden ? mode === "hide" : mode === "show" ) {
1143
			mode = "none";
1144
		}
1145
		return mode;
1146
	},
1147
1148
	// Translates a [top,left] array into a baseline value
1149
	getBaseline: function( origin, original ) {
1150
		var y, x;
1151
1152
		switch ( origin[ 0 ] ) {
1153
		case "top":
1154
			y = 0;
1155
			break;
1156
		case "middle":
1157
			y = 0.5;
1158
			break;
1159
		case "bottom":
1160
			y = 1;
1161
			break;
1162
		default:
1163
			y = origin[ 0 ] / original.height;
1164
		}
1165
1166
		switch ( origin[ 1 ] ) {
1167
		case "left":
1168
			x = 0;
1169
			break;
1170
		case "center":
1171
			x = 0.5;
1172
			break;
1173
		case "right":
1174
			x = 1;
1175
			break;
1176
		default:
1177
			x = origin[ 1 ] / original.width;
1178
		}
1179
1180
		return {
1181
			x: x,
1182
			y: y
1183
		};
1184
	},
1185
1186
	// Creates a placeholder element so that the original element can be made absolute
1187
	createPlaceholder: function( element ) {
1188
		var placeholder,
1189
			cssPosition = element.css( "position" ),
1190
			position = element.position();
1191
1192
		// Lock in margins first to account for form elements, which
1193
		// will change margin if you explicitly set height
1194
		// see: http://jsfiddle.net/JZSMt/3/ https://bugs.webkit.org/show_bug.cgi?id=107380
1195
		// Support: Safari
1196
		element.css( {
1197
			marginTop: element.css( "marginTop" ),
1198
			marginBottom: element.css( "marginBottom" ),
1199
			marginLeft: element.css( "marginLeft" ),
1200
			marginRight: element.css( "marginRight" )
1201
		} )
1202
		.outerWidth( element.outerWidth() )
1203
		.outerHeight( element.outerHeight() );
1204
1205
		if ( /^(static|relative)/.test( cssPosition ) ) {
1206
			cssPosition = "absolute";
1207
1208
			placeholder = $( "<" + element[ 0 ].nodeName + ">" ).insertAfter( element ).css( {
1209
1210
				// Convert inline to inline block to account for inline elements
1211
				// that turn to inline block based on content (like img)
1212
				display: /^(inline|ruby)/.test( element.css( "display" ) ) ?
1213
					"inline-block" :
1214
					"block",
1215
				visibility: "hidden",
1216
1217
				// Margins need to be set to account for margin collapse
1218
				marginTop: element.css( "marginTop" ),
1219
				marginBottom: element.css( "marginBottom" ),
1220
				marginLeft: element.css( "marginLeft" ),
1221
				marginRight: element.css( "marginRight" ),
1222
				"float": element.css( "float" )
1223
			} )
1224
			.outerWidth( element.outerWidth() )
1225
			.outerHeight( element.outerHeight() )
1226
			.addClass( "ui-effects-placeholder" );
1227
1228
			element.data( dataSpace + "placeholder", placeholder );
1229
		}
1230
1231
		element.css( {
1232
			position: cssPosition,
1233
			left: position.left,
1234
			top: position.top
1235
		} );
1236
1237
		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 1205 is false. Are you sure this can never be the case?
Loading history...
1238
	},
1239
1240
	removePlaceholder: function( element ) {
1241
		var dataKey = dataSpace + "placeholder",
1242
				placeholder = element.data( dataKey );
1243
1244
		if ( placeholder ) {
1245
			placeholder.remove();
1246
			element.removeData( dataKey );
1247
		}
1248
	},
1249
1250
	// Removes a placeholder if it exists and restores
1251
	// properties that were modified during placeholder creation
1252
	cleanUp: function( element ) {
1253
		$.effects.restoreStyle( element );
1254
		$.effects.removePlaceholder( element );
1255
	},
1256
1257
	setTransition: function( element, list, factor, value ) {
1258
		value = value || {};
1259
		$.each( list, function( i, x ) {
1260
			var unit = element.cssUnit( x );
1261
			if ( unit[ 0 ] > 0 ) {
1262
				value[ x ] = unit[ 0 ] * factor + unit[ 1 ];
1263
			}
1264
		} );
1265
		return value;
1266
	}
1267
} );
1268
1269
// Return an effect options object for the given parameters:
1270
function _normalizeArguments( effect, options, speed, callback ) {
1271
1272
	// Allow passing all options as the first parameter
1273
	if ( $.isPlainObject( effect ) ) {
1274
		options = effect;
1275
		effect = effect.effect;
1276
	}
1277
1278
	// Convert to an object
1279
	effect = { effect: effect };
1280
1281
	// Catch (effect, null, ...)
1282
	if ( options == null ) {
1283
		options = {};
1284
	}
1285
1286
	// Catch (effect, callback)
1287
	if ( $.isFunction( options ) ) {
1288
		callback = options;
1289
		speed = null;
1290
		options = {};
1291
	}
1292
1293
	// Catch (effect, speed, ?)
1294
	if ( typeof options === "number" || $.fx.speeds[ options ] ) {
1295
		callback = speed;
1296
		speed = options;
1297
		options = {};
1298
	}
1299
1300
	// Catch (effect, options, callback)
1301
	if ( $.isFunction( speed ) ) {
1302
		callback = speed;
1303
		speed = null;
1304
	}
1305
1306
	// Add options to effect
1307
	if ( options ) {
1308
		$.extend( effect, options );
1309
	}
1310
1311
	speed = speed || options.duration;
1312
	effect.duration = $.fx.off ? 0 :
1313
		typeof speed === "number" ? speed :
1314
		speed in $.fx.speeds ? $.fx.speeds[ speed ] :
1315
		$.fx.speeds._default;
1316
1317
	effect.complete = callback || options.complete;
1318
1319
	return effect;
1320
}
1321
1322
function standardAnimationOption( option ) {
1323
1324
	// Valid standard speeds (nothing, number, named speed)
1325
	if ( !option || typeof option === "number" || $.fx.speeds[ option ] ) {
1326
		return true;
1327
	}
1328
1329
	// Invalid strings - treat as "normal" speed
1330
	if ( typeof option === "string" && !$.effects.effect[ option ] ) {
1331
		return true;
1332
	}
1333
1334
	// Complete callback
1335
	if ( $.isFunction( option ) ) {
1336
		return true;
1337
	}
1338
1339
	// Options hash (but not naming an effect)
1340
	if ( typeof option === "object" && !option.effect ) {
1341
		return true;
1342
	}
1343
1344
	// Didn't match any standard API
1345
	return false;
1346
}
1347
1348
$.fn.extend( {
1349
	effect: function( /* effect, options, speed, callback */ ) {
1350
		var args = _normalizeArguments.apply( this, arguments ),
1351
			effectMethod = $.effects.effect[ args.effect ],
1352
			defaultMode = effectMethod.mode,
1353
			queue = args.queue,
1354
			queueName = queue || "fx",
1355
			complete = args.complete,
1356
			mode = args.mode,
1357
			modes = [],
1358
			prefilter = function( next ) {
1359
				var el = $( this ),
1360
					normalizedMode = $.effects.mode( el, mode ) || defaultMode;
1361
1362
				// Sentinel for duck-punching the :animated psuedo-selector
1363
				el.data( dataSpaceAnimated, true );
1364
1365
				// Save effect mode for later use,
1366
				// we can't just call $.effects.mode again later,
1367
				// as the .show() below destroys the initial state
1368
				modes.push( normalizedMode );
1369
1370
				// See $.uiBackCompat inside of run() for removal of defaultMode in 1.13
1371
				if ( defaultMode && ( normalizedMode === "show" ||
1372
						( normalizedMode === defaultMode && normalizedMode === "hide" ) ) ) {
1373
					el.show();
1374
				}
1375
1376
				if ( !defaultMode || normalizedMode !== "none" ) {
1377
					$.effects.saveStyle( el );
1378
				}
1379
1380
				if ( $.isFunction( next ) ) {
1381
					next();
1382
				}
1383
			};
1384
1385
		if ( $.fx.off || !effectMethod ) {
1386
1387
			// Delegate to the original method (e.g., .show()) if possible
1388
			if ( mode ) {
1389
				return this[ mode ]( args.duration, complete );
1390
			} else {
1391
				return this.each( function() {
1392
					if ( complete ) {
1393
						complete.call( this );
1394
					}
1395
				} );
1396
			}
1397
		}
1398
1399
		function run( next ) {
1400
			var elem = $( this );
1401
1402
			function cleanup() {
1403
				elem.removeData( dataSpaceAnimated );
1404
1405
				$.effects.cleanUp( elem );
1406
1407
				if ( args.mode === "hide" ) {
1408
					elem.hide();
1409
				}
1410
1411
				done();
1412
			}
1413
1414
			function done() {
1415
				if ( $.isFunction( complete ) ) {
1416
					complete.call( elem[ 0 ] );
1417
				}
1418
1419
				if ( $.isFunction( next ) ) {
1420
					next();
1421
				}
1422
			}
1423
1424
			// Override mode option on a per element basis,
1425
			// as toggle can be either show or hide depending on element state
1426
			args.mode = modes.shift();
1427
1428
			if ( $.uiBackCompat !== false && !defaultMode ) {
1429
				if ( elem.is( ":hidden" ) ? mode === "hide" : mode === "show" ) {
1430
1431
					// Call the core method to track "olddisplay" properly
1432
					elem[ mode ]();
1433
					done();
1434
				} else {
1435
					effectMethod.call( elem[ 0 ], args, done );
1436
				}
1437
			} else {
1438
				if ( args.mode === "none" ) {
1439
1440
					// Call the core method to track "olddisplay" properly
1441
					elem[ mode ]();
1442
					done();
1443
				} else {
1444
					effectMethod.call( elem[ 0 ], args, cleanup );
1445
				}
1446
			}
1447
		}
1448
1449
		// Run prefilter on all elements first to ensure that
1450
		// any showing or hiding happens before placeholder creation,
1451
		// which ensures that any layout changes are correctly captured.
1452
		return queue === false ?
1453
			this.each( prefilter ).each( run ) :
1454
			this.queue( queueName, prefilter ).queue( queueName, run );
1455
	},
1456
1457
	show: ( function( orig ) {
1458
		return function( option ) {
1459
			if ( standardAnimationOption( option ) ) {
1460
				return orig.apply( this, arguments );
1461
			} else {
1462
				var args = _normalizeArguments.apply( this, arguments );
1463
				args.mode = "show";
1464
				return this.effect.call( this, args );
1465
			}
1466
		};
1467
	} )( $.fn.show ),
1468
1469
	hide: ( function( orig ) {
1470
		return function( option ) {
1471
			if ( standardAnimationOption( option ) ) {
1472
				return orig.apply( this, arguments );
1473
			} else {
1474
				var args = _normalizeArguments.apply( this, arguments );
1475
				args.mode = "hide";
1476
				return this.effect.call( this, args );
1477
			}
1478
		};
1479
	} )( $.fn.hide ),
1480
1481
	toggle: ( function( orig ) {
1482
		return function( option ) {
1483
			if ( standardAnimationOption( option ) || typeof option === "boolean" ) {
1484
				return orig.apply( this, arguments );
1485
			} else {
1486
				var args = _normalizeArguments.apply( this, arguments );
1487
				args.mode = "toggle";
1488
				return this.effect.call( this, args );
1489
			}
1490
		};
1491
	} )( $.fn.toggle ),
1492
1493
	cssUnit: function( key ) {
1494
		var style = this.css( key ),
1495
			val = [];
1496
1497
		$.each( [ "em", "px", "%", "pt" ], function( i, unit ) {
1498
			if ( style.indexOf( unit ) > 0 ) {
1499
				val = [ parseFloat( style ), unit ];
1500
			}
1501
		} );
1502
		return val;
1503
	},
1504
1505
	cssClip: function( clipObj ) {
1506
		if ( clipObj ) {
1507
			return this.css( "clip", "rect(" + clipObj.top + "px " + clipObj.right + "px " +
1508
				clipObj.bottom + "px " + clipObj.left + "px)" );
1509
		}
1510
		return parseClip( this.css( "clip" ), this );
1511
	},
1512
1513
	transfer: function( options, done ) {
1514
		var element = $( this ),
1515
			target = $( options.to ),
1516
			targetFixed = target.css( "position" ) === "fixed",
1517
			body = $( "body" ),
1518
			fixTop = targetFixed ? body.scrollTop() : 0,
1519
			fixLeft = targetFixed ? body.scrollLeft() : 0,
1520
			endPosition = target.offset(),
1521
			animation = {
1522
				top: endPosition.top - fixTop,
1523
				left: endPosition.left - fixLeft,
1524
				height: target.innerHeight(),
1525
				width: target.innerWidth()
1526
			},
1527
			startPosition = element.offset(),
1528
			transfer = $( "<div class='ui-effects-transfer'></div>" )
1529
				.appendTo( "body" )
1530
				.addClass( options.className )
1531
				.css( {
1532
					top: startPosition.top - fixTop,
1533
					left: startPosition.left - fixLeft,
1534
					height: element.innerHeight(),
1535
					width: element.innerWidth(),
1536
					position: targetFixed ? "fixed" : "absolute"
1537
				} )
1538
				.animate( animation, options.duration, options.easing, function() {
1539
					transfer.remove();
1540
					if ( $.isFunction( done ) ) {
1541
						done();
1542
					}
1543
				} );
1544
	}
1545
} );
1546
1547
function parseClip( str, element ) {
1548
		var outerWidth = element.outerWidth(),
1549
			outerHeight = element.outerHeight(),
1550
			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)\)$/,
1551
			values = clipRegex.exec( str ) || [ "", 0, outerWidth, outerHeight, 0 ];
1552
1553
		return {
1554
			top: parseFloat( values[ 1 ] ) || 0,
1555
			right: values[ 2 ] === "auto" ? outerWidth : parseFloat( values[ 2 ] ),
1556
			bottom: values[ 3 ] === "auto" ? outerHeight : parseFloat( values[ 3 ] ),
1557
			left: parseFloat( values[ 4 ] ) || 0
1558
		};
1559
}
1560
1561
$.fx.step.clip = function( fx ) {
1562
	if ( !fx.clipInit ) {
1563
		fx.start = $( fx.elem ).cssClip();
1564
		if ( typeof fx.end === "string" ) {
1565
			fx.end = parseClip( fx.end, fx.elem );
1566
		}
1567
		fx.clipInit = true;
1568
	}
1569
1570
	$( fx.elem ).cssClip( {
1571
		top: fx.pos * ( fx.end.top - fx.start.top ) + fx.start.top,
1572
		right: fx.pos * ( fx.end.right - fx.start.right ) + fx.start.right,
1573
		bottom: fx.pos * ( fx.end.bottom - fx.start.bottom ) + fx.start.bottom,
1574
		left: fx.pos * ( fx.end.left - fx.start.left ) + fx.start.left
1575
	} );
1576
};
1577
1578
} )();
1579
1580
/******************************************************************************/
1581
/*********************************** EASING ***********************************/
1582
/******************************************************************************/
1583
1584
( function() {
1585
1586
// Based on easing equations from Robert Penner (http://www.robertpenner.com/easing)
1587
1588
var baseEasings = {};
1589
1590
$.each( [ "Quad", "Cubic", "Quart", "Quint", "Expo" ], function( i, name ) {
1591
	baseEasings[ name ] = function( p ) {
1592
		return Math.pow( p, i + 2 );
1593
	};
1594
} );
1595
1596
$.extend( baseEasings, {
1597
	Sine: function( p ) {
1598
		return 1 - Math.cos( p * Math.PI / 2 );
1599
	},
1600
	Circ: function( p ) {
1601
		return 1 - Math.sqrt( 1 - p * p );
1602
	},
1603
	Elastic: function( p ) {
1604
		return p === 0 || p === 1 ? p :
1605
			-Math.pow( 2, 8 * ( p - 1 ) ) * Math.sin( ( ( p - 1 ) * 80 - 7.5 ) * Math.PI / 15 );
1606
	},
1607
	Back: function( p ) {
1608
		return p * p * ( 3 * p - 2 );
1609
	},
1610
	Bounce: function( p ) {
1611
		var pow2,
1612
			bounce = 4;
1613
1614
		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...
1615
		return 1 / Math.pow( 4, 3 - bounce ) - 7.5625 * Math.pow( ( pow2 * 3 - 2 ) / 22 - p, 2 );
1616
	}
1617
} );
1618
1619
$.each( baseEasings, function( name, easeIn ) {
1620
	$.easing[ "easeIn" + name ] = easeIn;
1621
	$.easing[ "easeOut" + name ] = function( p ) {
1622
		return 1 - easeIn( 1 - p );
1623
	};
1624
	$.easing[ "easeInOut" + name ] = function( p ) {
1625
		return p < 0.5 ?
1626
			easeIn( p * 2 ) / 2 :
1627
			1 - easeIn( p * -2 + 2 ) / 2;
1628
	};
1629
} );
1630
1631
} )();
1632
1633
return $.effects;
1634
1635
} ) );
1636