1 import { jQuery
} from "./core.js";
2 import { document
} from "./var/document.js";
3 import { rcssNum
} from "./var/rcssNum.js";
4 import { rnothtmlwhite
} from "./var/rnothtmlwhite.js";
5 import { cssExpand
} from "./css/var/cssExpand.js";
6 import { isHiddenWithinTree
} from "./css/var/isHiddenWithinTree.js";
7 import { adjustCSS
} from "./css/adjustCSS.js";
8 import { cssCamelCase
} from "./css/cssCamelCase.js";
9 import { dataPriv
} from "./data/var/dataPriv.js";
10 import { showHide
} from "./css/showHide.js";
12 import "./core/init.js";
14 import "./deferred.js";
15 import "./traversing.js";
16 import "./manipulation.js";
18 import "./effects/Tween.js";
22 rfxtypes
= /^(?:toggle|show|hide)$/,
27 if ( document
.hidden
=== false && window
.requestAnimationFrame
) {
28 window
.requestAnimationFrame( schedule
);
30 window
.setTimeout( schedule
, 13 );
37 // Animations created synchronously will run synchronously
38 function createFxNow() {
39 window
.setTimeout( function() {
42 return ( fxNow
= Date
.now() );
45 // Generate parameters to create a standard animation
46 function genFx( type
, includeWidth
) {
49 attrs
= { height
: type
};
51 // If we include width, step value is 1 to do all cssExpand values,
52 // otherwise step value is 2 to skip over Left and Right
53 includeWidth
= includeWidth
? 1 : 0;
54 for ( ; i
< 4; i
+= 2 - includeWidth
) {
55 which
= cssExpand
[ i
];
56 attrs
[ "margin" + which
] = attrs
[ "padding" + which
] = type
;
60 attrs
.opacity
= attrs
.width
= type
;
66 function createTween( value
, prop
, animation
) {
68 collection
= ( Animation
.tweeners
[ prop
] || [] ).concat( Animation
.tweeners
[ "*" ] ),
70 length
= collection
.length
;
71 for ( ; index
< length
; index
++ ) {
72 if ( ( tween
= collection
[ index
].call( animation
, prop
, value
) ) ) {
74 // We're done with this property
80 function defaultPrefilter( elem
, props
, opts
) {
81 var prop
, value
, toggle
, hooks
, oldfire
, propTween
, restoreDisplay
, display
,
82 isBox
= "width" in props
|| "height" in props
,
86 hidden
= elem
.nodeType
&& isHiddenWithinTree( elem
),
87 dataShow
= dataPriv
.get( elem
, "fxshow" );
89 // Queue-skipping animations hijack the fx hooks
91 hooks
= jQuery
._queueHooks( elem
, "fx" );
92 if ( hooks
.unqueued
== null ) {
94 oldfire
= hooks
.empty
.fire
;
95 hooks
.empty
.fire = function() {
96 if ( !hooks
.unqueued
) {
103 anim
.always( function() {
105 // Ensure the complete handler is called before this completes
106 anim
.always( function() {
108 if ( !jQuery
.queue( elem
, "fx" ).length
) {
115 // Detect show/hide animations
116 for ( prop
in props
) {
117 value
= props
[ prop
];
118 if ( rfxtypes
.test( value
) ) {
119 delete props
[ prop
];
120 toggle
= toggle
|| value
=== "toggle";
121 if ( value
=== ( hidden
? "hide" : "show" ) ) {
123 // Pretend to be hidden if this is a "show" and
124 // there is still data from a stopped show/hide
125 if ( value
=== "show" && dataShow
&& dataShow
[ prop
] !== undefined ) {
128 // Ignore all other no-op show/hide data
133 orig
[ prop
] = dataShow
&& dataShow
[ prop
] || jQuery
.style( elem
, prop
);
137 // Bail out if this is a no-op like .hide().hide()
138 propTween
= !jQuery
.isEmptyObject( props
);
139 if ( !propTween
&& jQuery
.isEmptyObject( orig
) ) {
143 // Restrict "overflow" and "display" styles during box animations
144 if ( isBox
&& elem
.nodeType
=== 1 ) {
146 // Support: IE <=9 - 11+
147 // Record all 3 overflow attributes because IE does not infer the shorthand
148 // from identically-valued overflowX and overflowY.
149 opts
.overflow
= [ style
.overflow
, style
.overflowX
, style
.overflowY
];
151 // Identify a display type, preferring old show/hide data over the CSS cascade
152 restoreDisplay
= dataShow
&& dataShow
.display
;
153 if ( restoreDisplay
== null ) {
154 restoreDisplay
= dataPriv
.get( elem
, "display" );
156 display
= jQuery
.css( elem
, "display" );
157 if ( display
=== "none" ) {
158 if ( restoreDisplay
) {
159 display
= restoreDisplay
;
162 // Get nonempty value(s) by temporarily forcing visibility
163 showHide( [ elem
], true );
164 restoreDisplay
= elem
.style
.display
|| restoreDisplay
;
165 display
= jQuery
.css( elem
, "display" );
166 showHide( [ elem
] );
170 // Animate inline elements as inline-block
171 if ( display
=== "inline" || display
=== "inline-block" && restoreDisplay
!= null ) {
172 if ( jQuery
.css( elem
, "float" ) === "none" ) {
174 // Restore the original display value at the end of pure show/hide animations
176 anim
.done( function() {
177 style
.display
= restoreDisplay
;
179 if ( restoreDisplay
== null ) {
180 display
= style
.display
;
181 restoreDisplay
= display
=== "none" ? "" : display
;
184 style
.display
= "inline-block";
189 if ( opts
.overflow
) {
190 style
.overflow
= "hidden";
191 anim
.always( function() {
192 style
.overflow
= opts
.overflow
[ 0 ];
193 style
.overflowX
= opts
.overflow
[ 1 ];
194 style
.overflowY
= opts
.overflow
[ 2 ];
198 // Implement show/hide animations
200 for ( prop
in orig
) {
202 // General show/hide setup for this element animation
205 if ( "hidden" in dataShow
) {
206 hidden
= dataShow
.hidden
;
209 dataShow
= dataPriv
.access( elem
, "fxshow", { display
: restoreDisplay
} );
212 // Store hidden/visible for toggle so `.stop().toggle()` "reverses"
214 dataShow
.hidden
= !hidden
;
217 // Show elements before animating them
219 showHide( [ elem
], true );
222 // eslint-disable-next-line no-loop-func
223 anim
.done( function() {
225 // The final step of a "hide" animation is actually hiding the element
227 showHide( [ elem
] );
229 dataPriv
.remove( elem
, "fxshow" );
230 for ( prop
in orig
) {
231 jQuery
.style( elem
, prop
, orig
[ prop
] );
236 // Per-property setup
237 propTween
= createTween( hidden
? dataShow
[ prop
] : 0, prop
, anim
);
238 if ( !( prop
in dataShow
) ) {
239 dataShow
[ prop
] = propTween
.start
;
241 propTween
.end
= propTween
.start
;
248 function propFilter( props
, specialEasing
) {
249 var index
, name
, easing
, value
, hooks
;
251 // camelCase, specialEasing and expand cssHook pass
252 for ( index
in props
) {
253 name
= cssCamelCase( index
);
254 easing
= specialEasing
[ name
];
255 value
= props
[ index
];
256 if ( Array
.isArray( value
) ) {
258 value
= props
[ index
] = value
[ 0 ];
261 if ( index
!== name
) {
262 props
[ name
] = value
;
263 delete props
[ index
];
266 hooks
= jQuery
.cssHooks
[ name
];
267 if ( hooks
&& "expand" in hooks
) {
268 value
= hooks
.expand( value
);
269 delete props
[ name
];
271 // Not quite $.extend, this won't overwrite existing keys.
272 // Reusing 'index' because we have the correct "name"
273 for ( index
in value
) {
274 if ( !( index
in props
) ) {
275 props
[ index
] = value
[ index
];
276 specialEasing
[ index
] = easing
;
280 specialEasing
[ name
] = easing
;
285 function Animation( elem
, properties
, options
) {
289 length
= Animation
.prefilters
.length
,
290 deferred
= jQuery
.Deferred().always( function() {
292 // Don't match elem in the :animated selector
299 var currentTime
= fxNow
|| createFxNow(),
300 remaining
= Math
.max( 0, animation
.startTime
+ animation
.duration
- currentTime
),
302 percent
= 1 - ( remaining
/ animation
.duration
|| 0 ),
304 length
= animation
.tweens
.length
;
306 for ( ; index
< length
; index
++ ) {
307 animation
.tweens
[ index
].run( percent
);
310 deferred
.notifyWith( elem
, [ animation
, percent
, remaining
] );
312 // If there's more to do, yield
313 if ( percent
< 1 && length
) {
317 // If this was an empty animation, synthesize a final progress notification
319 deferred
.notifyWith( elem
, [ animation
, 1, 0 ] );
322 // Resolve the animation and report its conclusion
323 deferred
.resolveWith( elem
, [ animation
] );
326 animation
= deferred
.promise( {
328 props
: jQuery
.extend( {}, properties
),
329 opts
: jQuery
.extend( true, {
331 easing
: jQuery
.easing
._default
333 originalProperties
: properties
,
334 originalOptions
: options
,
335 startTime
: fxNow
|| createFxNow(),
336 duration
: options
.duration
,
338 createTween: function( prop
, end
) {
339 var tween
= jQuery
.Tween( elem
, animation
.opts
, prop
, end
,
340 animation
.opts
.specialEasing
[ prop
] || animation
.opts
.easing
);
341 animation
.tweens
.push( tween
);
344 stop: function( gotoEnd
) {
347 // If we are going to the end, we want to run all the tweens
348 // otherwise we skip this part
349 length
= gotoEnd
? animation
.tweens
.length
: 0;
354 for ( ; index
< length
; index
++ ) {
355 animation
.tweens
[ index
].run( 1 );
358 // Resolve when we played the last frame; otherwise, reject
360 deferred
.notifyWith( elem
, [ animation
, 1, 0 ] );
361 deferred
.resolveWith( elem
, [ animation
, gotoEnd
] );
363 deferred
.rejectWith( elem
, [ animation
, gotoEnd
] );
368 props
= animation
.props
;
370 propFilter( props
, animation
.opts
.specialEasing
);
372 for ( ; index
< length
; index
++ ) {
373 result
= Animation
.prefilters
[ index
].call( animation
, elem
, props
, animation
.opts
);
375 if ( typeof result
.stop
=== "function" ) {
376 jQuery
._queueHooks( animation
.elem
, animation
.opts
.queue
).stop
=
377 result
.stop
.bind( result
);
383 jQuery
.map( props
, createTween
, animation
);
385 if ( typeof animation
.opts
.start
=== "function" ) {
386 animation
.opts
.start
.call( elem
, animation
);
389 // Attach callbacks from options
391 .progress( animation
.opts
.progress
)
392 .done( animation
.opts
.done
, animation
.opts
.complete
)
393 .fail( animation
.opts
.fail
)
394 .always( animation
.opts
.always
);
397 jQuery
.extend( tick
, {
400 queue
: animation
.opts
.queue
407 jQuery
.Animation
= jQuery
.extend( Animation
, {
410 "*": [ function( prop
, value
) {
411 var tween
= this.createTween( prop
, value
);
412 adjustCSS( tween
.elem
, prop
, rcssNum
.exec( value
), tween
);
417 tweener: function( props
, callback
) {
418 if ( typeof props
=== "function" ) {
422 props
= props
.match( rnothtmlwhite
);
427 length
= props
.length
;
429 for ( ; index
< length
; index
++ ) {
430 prop
= props
[ index
];
431 Animation
.tweeners
[ prop
] = Animation
.tweeners
[ prop
] || [];
432 Animation
.tweeners
[ prop
].unshift( callback
);
436 prefilters
: [ defaultPrefilter
],
438 prefilter: function( callback
, prepend
) {
440 Animation
.prefilters
.unshift( callback
);
442 Animation
.prefilters
.push( callback
);
447 jQuery
.speed = function( speed
, easing
, fn
) {
448 var opt
= speed
&& typeof speed
=== "object" ? jQuery
.extend( {}, speed
) : {
449 complete
: fn
|| easing
||
450 typeof speed
=== "function" && speed
,
452 easing
: fn
&& easing
|| easing
&& typeof easing
!== "function" && easing
455 // Go to the end state if fx are off
456 if ( jQuery
.fx
.off
) {
460 if ( typeof opt
.duration
!== "number" ) {
461 if ( opt
.duration
in jQuery
.fx
.speeds
) {
462 opt
.duration
= jQuery
.fx
.speeds
[ opt
.duration
];
465 opt
.duration
= jQuery
.fx
.speeds
._default
;
470 // Normalize opt.queue - true/undefined/null -> "fx"
471 if ( opt
.queue
== null || opt
.queue
=== true ) {
476 opt
.old
= opt
.complete
;
478 opt
.complete = function() {
479 if ( typeof opt
.old
=== "function" ) {
480 opt
.old
.call( this );
484 jQuery
.dequeue( this, opt
.queue
);
492 fadeTo: function( speed
, to
, easing
, callback
) {
494 // Show any hidden elements after setting opacity to 0
495 return this.filter( isHiddenWithinTree
).css( "opacity", 0 ).show()
497 // Animate to the value specified
498 .end().animate( { opacity
: to
}, speed
, easing
, callback
);
500 animate: function( prop
, speed
, easing
, callback
) {
501 var empty
= jQuery
.isEmptyObject( prop
),
502 optall
= jQuery
.speed( speed
, easing
, callback
),
503 doAnimation = function() {
505 // Operate on a copy of prop so per-property easing won't be lost
506 var anim
= Animation( this, jQuery
.extend( {}, prop
), optall
);
508 // Empty animations, or finishing resolves immediately
509 if ( empty
|| dataPriv
.get( this, "finish" ) ) {
514 doAnimation
.finish
= doAnimation
;
516 return empty
|| optall
.queue
=== false ?
517 this.each( doAnimation
) :
518 this.queue( optall
.queue
, doAnimation
);
520 stop: function( type
, clearQueue
, gotoEnd
) {
521 var stopQueue = function( hooks
) {
522 var stop
= hooks
.stop
;
527 if ( typeof type
!== "string" ) {
528 gotoEnd
= clearQueue
;
533 this.queue( type
|| "fx", [] );
536 return this.each( function() {
538 index
= type
!= null && type
+ "queueHooks",
539 timers
= jQuery
.timers
,
540 data
= dataPriv
.get( this );
543 if ( data
[ index
] && data
[ index
].stop
) {
544 stopQueue( data
[ index
] );
547 for ( index
in data
) {
548 if ( data
[ index
] && data
[ index
].stop
&& rrun
.test( index
) ) {
549 stopQueue( data
[ index
] );
554 for ( index
= timers
.length
; index
--; ) {
555 if ( timers
[ index
].elem
=== this &&
556 ( type
== null || timers
[ index
].queue
=== type
) ) {
558 timers
[ index
].anim
.stop( gotoEnd
);
560 timers
.splice( index
, 1 );
564 // Start the next in the queue if the last step wasn't forced.
565 // Timers currently will call their complete callbacks, which
566 // will dequeue but only if they were gotoEnd.
567 if ( dequeue
|| !gotoEnd
) {
568 jQuery
.dequeue( this, type
);
572 finish: function( type
) {
573 if ( type
!== false ) {
576 return this.each( function() {
578 data
= dataPriv
.get( this ),
579 queue
= data
[ type
+ "queue" ],
580 hooks
= data
[ type
+ "queueHooks" ],
581 timers
= jQuery
.timers
,
582 length
= queue
? queue
.length
: 0;
584 // Enable finishing flag on private data
587 // Empty the queue first
588 jQuery
.queue( this, type
, [] );
590 if ( hooks
&& hooks
.stop
) {
591 hooks
.stop
.call( this, true );
594 // Look for any active animations, and finish them
595 for ( index
= timers
.length
; index
--; ) {
596 if ( timers
[ index
].elem
=== this && timers
[ index
].queue
=== type
) {
597 timers
[ index
].anim
.stop( true );
598 timers
.splice( index
, 1 );
602 // Look for any animations in the old queue and finish them
603 for ( index
= 0; index
< length
; index
++ ) {
604 if ( queue
[ index
] && queue
[ index
].finish
) {
605 queue
[ index
].finish
.call( this );
609 // Turn off finishing flag
615 jQuery
.each( [ "toggle", "show", "hide" ], function( _i
, name
) {
616 var cssFn
= jQuery
.fn
[ name
];
617 jQuery
.fn
[ name
] = function( speed
, easing
, callback
) {
618 return speed
== null || typeof speed
=== "boolean" ?
619 cssFn
.apply( this, arguments
) :
620 this.animate( genFx( name
, true ), speed
, easing
, callback
);
624 // Generate shortcuts for custom animations
626 slideDown
: genFx( "show" ),
627 slideUp
: genFx( "hide" ),
628 slideToggle
: genFx( "toggle" ),
629 fadeIn
: { opacity
: "show" },
630 fadeOut
: { opacity
: "hide" },
631 fadeToggle
: { opacity
: "toggle" }
632 }, function( name
, props
) {
633 jQuery
.fn
[ name
] = function( speed
, easing
, callback
) {
634 return this.animate( props
, speed
, easing
, callback
);
639 jQuery
.fx
.tick = function() {
642 timers
= jQuery
.timers
;
646 for ( ; i
< timers
.length
; i
++ ) {
649 // Run the timer and safely remove it when done (allowing for external removal)
650 if ( !timer() && timers
[ i
] === timer
) {
651 timers
.splice( i
--, 1 );
655 if ( !timers
.length
) {
661 jQuery
.fx
.timer = function( timer
) {
662 jQuery
.timers
.push( timer
);
666 jQuery
.fx
.start = function() {
675 jQuery
.fx
.stop = function() {
687 export { jQuery
, jQuery as
$ };