Copybara bot | be50d49 | 2023-11-30 00:16:42 +0100 | [diff] [blame] | 1 | define( [ |
| 2 | "./core", |
| 3 | "./core/camelCase", |
| 4 | "./var/document", |
| 5 | "./var/isFunction", |
| 6 | "./var/rcssNum", |
| 7 | "./var/rnothtmlwhite", |
| 8 | "./css/var/cssExpand", |
| 9 | "./css/var/isHiddenWithinTree", |
| 10 | "./css/var/swap", |
| 11 | "./css/adjustCSS", |
| 12 | "./data/var/dataPriv", |
| 13 | "./css/showHide", |
| 14 | |
| 15 | "./core/init", |
| 16 | "./queue", |
| 17 | "./deferred", |
| 18 | "./traversing", |
| 19 | "./manipulation", |
| 20 | "./css", |
| 21 | "./effects/Tween" |
| 22 | ], function( jQuery, camelCase, document, isFunction, rcssNum, rnothtmlwhite, cssExpand, |
| 23 | isHiddenWithinTree, swap, adjustCSS, dataPriv, showHide ) { |
| 24 | |
| 25 | "use strict"; |
| 26 | |
| 27 | var |
| 28 | fxNow, inProgress, |
| 29 | rfxtypes = /^(?:toggle|show|hide)$/, |
| 30 | rrun = /queueHooks$/; |
| 31 | |
| 32 | function schedule() { |
| 33 | if ( inProgress ) { |
| 34 | if ( document.hidden === false && window.requestAnimationFrame ) { |
| 35 | window.requestAnimationFrame( schedule ); |
| 36 | } else { |
| 37 | window.setTimeout( schedule, jQuery.fx.interval ); |
| 38 | } |
| 39 | |
| 40 | jQuery.fx.tick(); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | // Animations created synchronously will run synchronously |
| 45 | function createFxNow() { |
| 46 | window.setTimeout( function() { |
| 47 | fxNow = undefined; |
| 48 | } ); |
| 49 | return ( fxNow = Date.now() ); |
| 50 | } |
| 51 | |
| 52 | // Generate parameters to create a standard animation |
| 53 | function genFx( type, includeWidth ) { |
| 54 | var which, |
| 55 | i = 0, |
| 56 | attrs = { height: type }; |
| 57 | |
| 58 | // If we include width, step value is 1 to do all cssExpand values, |
| 59 | // otherwise step value is 2 to skip over Left and Right |
| 60 | includeWidth = includeWidth ? 1 : 0; |
| 61 | for ( ; i < 4; i += 2 - includeWidth ) { |
| 62 | which = cssExpand[ i ]; |
| 63 | attrs[ "margin" + which ] = attrs[ "padding" + which ] = type; |
| 64 | } |
| 65 | |
| 66 | if ( includeWidth ) { |
| 67 | attrs.opacity = attrs.width = type; |
| 68 | } |
| 69 | |
| 70 | return attrs; |
| 71 | } |
| 72 | |
| 73 | function createTween( value, prop, animation ) { |
| 74 | var tween, |
| 75 | collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ), |
| 76 | index = 0, |
| 77 | length = collection.length; |
| 78 | for ( ; index < length; index++ ) { |
| 79 | if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) { |
| 80 | |
| 81 | // We're done with this property |
| 82 | return tween; |
| 83 | } |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | function defaultPrefilter( elem, props, opts ) { |
| 88 | var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display, |
| 89 | isBox = "width" in props || "height" in props, |
| 90 | anim = this, |
| 91 | orig = {}, |
| 92 | style = elem.style, |
| 93 | hidden = elem.nodeType && isHiddenWithinTree( elem ), |
| 94 | dataShow = dataPriv.get( elem, "fxshow" ); |
| 95 | |
| 96 | // Queue-skipping animations hijack the fx hooks |
| 97 | if ( !opts.queue ) { |
| 98 | hooks = jQuery._queueHooks( elem, "fx" ); |
| 99 | if ( hooks.unqueued == null ) { |
| 100 | hooks.unqueued = 0; |
| 101 | oldfire = hooks.empty.fire; |
| 102 | hooks.empty.fire = function() { |
| 103 | if ( !hooks.unqueued ) { |
| 104 | oldfire(); |
| 105 | } |
| 106 | }; |
| 107 | } |
| 108 | hooks.unqueued++; |
| 109 | |
| 110 | anim.always( function() { |
| 111 | |
| 112 | // Ensure the complete handler is called before this completes |
| 113 | anim.always( function() { |
| 114 | hooks.unqueued--; |
| 115 | if ( !jQuery.queue( elem, "fx" ).length ) { |
| 116 | hooks.empty.fire(); |
| 117 | } |
| 118 | } ); |
| 119 | } ); |
| 120 | } |
| 121 | |
| 122 | // Detect show/hide animations |
| 123 | for ( prop in props ) { |
| 124 | value = props[ prop ]; |
| 125 | if ( rfxtypes.test( value ) ) { |
| 126 | delete props[ prop ]; |
| 127 | toggle = toggle || value === "toggle"; |
| 128 | if ( value === ( hidden ? "hide" : "show" ) ) { |
| 129 | |
| 130 | // Pretend to be hidden if this is a "show" and |
| 131 | // there is still data from a stopped show/hide |
| 132 | if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) { |
| 133 | hidden = true; |
| 134 | |
| 135 | // Ignore all other no-op show/hide data |
| 136 | } else { |
| 137 | continue; |
| 138 | } |
| 139 | } |
| 140 | orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop ); |
| 141 | } |
| 142 | } |
| 143 | |
| 144 | // Bail out if this is a no-op like .hide().hide() |
| 145 | propTween = !jQuery.isEmptyObject( props ); |
| 146 | if ( !propTween && jQuery.isEmptyObject( orig ) ) { |
| 147 | return; |
| 148 | } |
| 149 | |
| 150 | // Restrict "overflow" and "display" styles during box animations |
| 151 | if ( isBox && elem.nodeType === 1 ) { |
| 152 | |
| 153 | // Support: IE <=9 - 11, Edge 12 - 15 |
| 154 | // Record all 3 overflow attributes because IE does not infer the shorthand |
| 155 | // from identically-valued overflowX and overflowY and Edge just mirrors |
| 156 | // the overflowX value there. |
| 157 | opts.overflow = [ style.overflow, style.overflowX, style.overflowY ]; |
| 158 | |
| 159 | // Identify a display type, preferring old show/hide data over the CSS cascade |
| 160 | restoreDisplay = dataShow && dataShow.display; |
| 161 | if ( restoreDisplay == null ) { |
| 162 | restoreDisplay = dataPriv.get( elem, "display" ); |
| 163 | } |
| 164 | display = jQuery.css( elem, "display" ); |
| 165 | if ( display === "none" ) { |
| 166 | if ( restoreDisplay ) { |
| 167 | display = restoreDisplay; |
| 168 | } else { |
| 169 | |
| 170 | // Get nonempty value(s) by temporarily forcing visibility |
| 171 | showHide( [ elem ], true ); |
| 172 | restoreDisplay = elem.style.display || restoreDisplay; |
| 173 | display = jQuery.css( elem, "display" ); |
| 174 | showHide( [ elem ] ); |
| 175 | } |
| 176 | } |
| 177 | |
| 178 | // Animate inline elements as inline-block |
| 179 | if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) { |
| 180 | if ( jQuery.css( elem, "float" ) === "none" ) { |
| 181 | |
| 182 | // Restore the original display value at the end of pure show/hide animations |
| 183 | if ( !propTween ) { |
| 184 | anim.done( function() { |
| 185 | style.display = restoreDisplay; |
| 186 | } ); |
| 187 | if ( restoreDisplay == null ) { |
| 188 | display = style.display; |
| 189 | restoreDisplay = display === "none" ? "" : display; |
| 190 | } |
| 191 | } |
| 192 | style.display = "inline-block"; |
| 193 | } |
| 194 | } |
| 195 | } |
| 196 | |
| 197 | if ( opts.overflow ) { |
| 198 | style.overflow = "hidden"; |
| 199 | anim.always( function() { |
| 200 | style.overflow = opts.overflow[ 0 ]; |
| 201 | style.overflowX = opts.overflow[ 1 ]; |
| 202 | style.overflowY = opts.overflow[ 2 ]; |
| 203 | } ); |
| 204 | } |
| 205 | |
| 206 | // Implement show/hide animations |
| 207 | propTween = false; |
| 208 | for ( prop in orig ) { |
| 209 | |
| 210 | // General show/hide setup for this element animation |
| 211 | if ( !propTween ) { |
| 212 | if ( dataShow ) { |
| 213 | if ( "hidden" in dataShow ) { |
| 214 | hidden = dataShow.hidden; |
| 215 | } |
| 216 | } else { |
| 217 | dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } ); |
| 218 | } |
| 219 | |
| 220 | // Store hidden/visible for toggle so `.stop().toggle()` "reverses" |
| 221 | if ( toggle ) { |
| 222 | dataShow.hidden = !hidden; |
| 223 | } |
| 224 | |
| 225 | // Show elements before animating them |
| 226 | if ( hidden ) { |
| 227 | showHide( [ elem ], true ); |
| 228 | } |
| 229 | |
| 230 | /* eslint-disable no-loop-func */ |
| 231 | |
| 232 | anim.done( function() { |
| 233 | |
| 234 | /* eslint-enable no-loop-func */ |
| 235 | |
| 236 | // The final step of a "hide" animation is actually hiding the element |
| 237 | if ( !hidden ) { |
| 238 | showHide( [ elem ] ); |
| 239 | } |
| 240 | dataPriv.remove( elem, "fxshow" ); |
| 241 | for ( prop in orig ) { |
| 242 | jQuery.style( elem, prop, orig[ prop ] ); |
| 243 | } |
| 244 | } ); |
| 245 | } |
| 246 | |
| 247 | // Per-property setup |
| 248 | propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim ); |
| 249 | if ( !( prop in dataShow ) ) { |
| 250 | dataShow[ prop ] = propTween.start; |
| 251 | if ( hidden ) { |
| 252 | propTween.end = propTween.start; |
| 253 | propTween.start = 0; |
| 254 | } |
| 255 | } |
| 256 | } |
| 257 | } |
| 258 | |
| 259 | function propFilter( props, specialEasing ) { |
| 260 | var index, name, easing, value, hooks; |
| 261 | |
| 262 | // camelCase, specialEasing and expand cssHook pass |
| 263 | for ( index in props ) { |
| 264 | name = camelCase( index ); |
| 265 | easing = specialEasing[ name ]; |
| 266 | value = props[ index ]; |
| 267 | if ( Array.isArray( value ) ) { |
| 268 | easing = value[ 1 ]; |
| 269 | value = props[ index ] = value[ 0 ]; |
| 270 | } |
| 271 | |
| 272 | if ( index !== name ) { |
| 273 | props[ name ] = value; |
| 274 | delete props[ index ]; |
| 275 | } |
| 276 | |
| 277 | hooks = jQuery.cssHooks[ name ]; |
| 278 | if ( hooks && "expand" in hooks ) { |
| 279 | value = hooks.expand( value ); |
| 280 | delete props[ name ]; |
| 281 | |
| 282 | // Not quite $.extend, this won't overwrite existing keys. |
| 283 | // Reusing 'index' because we have the correct "name" |
| 284 | for ( index in value ) { |
| 285 | if ( !( index in props ) ) { |
| 286 | props[ index ] = value[ index ]; |
| 287 | specialEasing[ index ] = easing; |
| 288 | } |
| 289 | } |
| 290 | } else { |
| 291 | specialEasing[ name ] = easing; |
| 292 | } |
| 293 | } |
| 294 | } |
| 295 | |
| 296 | function Animation( elem, properties, options ) { |
| 297 | var result, |
| 298 | stopped, |
| 299 | index = 0, |
| 300 | length = Animation.prefilters.length, |
| 301 | deferred = jQuery.Deferred().always( function() { |
| 302 | |
| 303 | // Don't match elem in the :animated selector |
| 304 | delete tick.elem; |
| 305 | } ), |
| 306 | tick = function() { |
| 307 | if ( stopped ) { |
| 308 | return false; |
| 309 | } |
| 310 | var currentTime = fxNow || createFxNow(), |
| 311 | remaining = Math.max( 0, animation.startTime + animation.duration - currentTime ), |
| 312 | |
| 313 | // Support: Android 2.3 only |
| 314 | // Archaic crash bug won't allow us to use `1 - ( 0.5 || 0 )` (#12497) |
| 315 | temp = remaining / animation.duration || 0, |
| 316 | percent = 1 - temp, |
| 317 | index = 0, |
| 318 | length = animation.tweens.length; |
| 319 | |
| 320 | for ( ; index < length; index++ ) { |
| 321 | animation.tweens[ index ].run( percent ); |
| 322 | } |
| 323 | |
| 324 | deferred.notifyWith( elem, [ animation, percent, remaining ] ); |
| 325 | |
| 326 | // If there's more to do, yield |
| 327 | if ( percent < 1 && length ) { |
| 328 | return remaining; |
| 329 | } |
| 330 | |
| 331 | // If this was an empty animation, synthesize a final progress notification |
| 332 | if ( !length ) { |
| 333 | deferred.notifyWith( elem, [ animation, 1, 0 ] ); |
| 334 | } |
| 335 | |
| 336 | // Resolve the animation and report its conclusion |
| 337 | deferred.resolveWith( elem, [ animation ] ); |
| 338 | return false; |
| 339 | }, |
| 340 | animation = deferred.promise( { |
| 341 | elem: elem, |
| 342 | props: jQuery.extend( {}, properties ), |
| 343 | opts: jQuery.extend( true, { |
| 344 | specialEasing: {}, |
| 345 | easing: jQuery.easing._default |
| 346 | }, options ), |
| 347 | originalProperties: properties, |
| 348 | originalOptions: options, |
| 349 | startTime: fxNow || createFxNow(), |
| 350 | duration: options.duration, |
| 351 | tweens: [], |
| 352 | createTween: function( prop, end ) { |
| 353 | var tween = jQuery.Tween( elem, animation.opts, prop, end, |
| 354 | animation.opts.specialEasing[ prop ] || animation.opts.easing ); |
| 355 | animation.tweens.push( tween ); |
| 356 | return tween; |
| 357 | }, |
| 358 | stop: function( gotoEnd ) { |
| 359 | var index = 0, |
| 360 | |
| 361 | // If we are going to the end, we want to run all the tweens |
| 362 | // otherwise we skip this part |
| 363 | length = gotoEnd ? animation.tweens.length : 0; |
| 364 | if ( stopped ) { |
| 365 | return this; |
| 366 | } |
| 367 | stopped = true; |
| 368 | for ( ; index < length; index++ ) { |
| 369 | animation.tweens[ index ].run( 1 ); |
| 370 | } |
| 371 | |
| 372 | // Resolve when we played the last frame; otherwise, reject |
| 373 | if ( gotoEnd ) { |
| 374 | deferred.notifyWith( elem, [ animation, 1, 0 ] ); |
| 375 | deferred.resolveWith( elem, [ animation, gotoEnd ] ); |
| 376 | } else { |
| 377 | deferred.rejectWith( elem, [ animation, gotoEnd ] ); |
| 378 | } |
| 379 | return this; |
| 380 | } |
| 381 | } ), |
| 382 | props = animation.props; |
| 383 | |
| 384 | propFilter( props, animation.opts.specialEasing ); |
| 385 | |
| 386 | for ( ; index < length; index++ ) { |
| 387 | result = Animation.prefilters[ index ].call( animation, elem, props, animation.opts ); |
| 388 | if ( result ) { |
| 389 | if ( isFunction( result.stop ) ) { |
| 390 | jQuery._queueHooks( animation.elem, animation.opts.queue ).stop = |
| 391 | result.stop.bind( result ); |
| 392 | } |
| 393 | return result; |
| 394 | } |
| 395 | } |
| 396 | |
| 397 | jQuery.map( props, createTween, animation ); |
| 398 | |
| 399 | if ( isFunction( animation.opts.start ) ) { |
| 400 | animation.opts.start.call( elem, animation ); |
| 401 | } |
| 402 | |
| 403 | // Attach callbacks from options |
| 404 | animation |
| 405 | .progress( animation.opts.progress ) |
| 406 | .done( animation.opts.done, animation.opts.complete ) |
| 407 | .fail( animation.opts.fail ) |
| 408 | .always( animation.opts.always ); |
| 409 | |
| 410 | jQuery.fx.timer( |
| 411 | jQuery.extend( tick, { |
| 412 | elem: elem, |
| 413 | anim: animation, |
| 414 | queue: animation.opts.queue |
| 415 | } ) |
| 416 | ); |
| 417 | |
| 418 | return animation; |
| 419 | } |
| 420 | |
| 421 | jQuery.Animation = jQuery.extend( Animation, { |
| 422 | |
| 423 | tweeners: { |
| 424 | "*": [ function( prop, value ) { |
| 425 | var tween = this.createTween( prop, value ); |
| 426 | adjustCSS( tween.elem, prop, rcssNum.exec( value ), tween ); |
| 427 | return tween; |
| 428 | } ] |
| 429 | }, |
| 430 | |
| 431 | tweener: function( props, callback ) { |
| 432 | if ( isFunction( props ) ) { |
| 433 | callback = props; |
| 434 | props = [ "*" ]; |
| 435 | } else { |
| 436 | props = props.match( rnothtmlwhite ); |
| 437 | } |
| 438 | |
| 439 | var prop, |
| 440 | index = 0, |
| 441 | length = props.length; |
| 442 | |
| 443 | for ( ; index < length; index++ ) { |
| 444 | prop = props[ index ]; |
| 445 | Animation.tweeners[ prop ] = Animation.tweeners[ prop ] || []; |
| 446 | Animation.tweeners[ prop ].unshift( callback ); |
| 447 | } |
| 448 | }, |
| 449 | |
| 450 | prefilters: [ defaultPrefilter ], |
| 451 | |
| 452 | prefilter: function( callback, prepend ) { |
| 453 | if ( prepend ) { |
| 454 | Animation.prefilters.unshift( callback ); |
| 455 | } else { |
| 456 | Animation.prefilters.push( callback ); |
| 457 | } |
| 458 | } |
| 459 | } ); |
| 460 | |
| 461 | jQuery.speed = function( speed, easing, fn ) { |
| 462 | var opt = speed && typeof speed === "object" ? jQuery.extend( {}, speed ) : { |
| 463 | complete: fn || !fn && easing || |
| 464 | isFunction( speed ) && speed, |
| 465 | duration: speed, |
| 466 | easing: fn && easing || easing && !isFunction( easing ) && easing |
| 467 | }; |
| 468 | |
| 469 | // Go to the end state if fx are off |
| 470 | if ( jQuery.fx.off ) { |
| 471 | opt.duration = 0; |
| 472 | |
| 473 | } else { |
| 474 | if ( typeof opt.duration !== "number" ) { |
| 475 | if ( opt.duration in jQuery.fx.speeds ) { |
| 476 | opt.duration = jQuery.fx.speeds[ opt.duration ]; |
| 477 | |
| 478 | } else { |
| 479 | opt.duration = jQuery.fx.speeds._default; |
| 480 | } |
| 481 | } |
| 482 | } |
| 483 | |
| 484 | // Normalize opt.queue - true/undefined/null -> "fx" |
| 485 | if ( opt.queue == null || opt.queue === true ) { |
| 486 | opt.queue = "fx"; |
| 487 | } |
| 488 | |
| 489 | // Queueing |
| 490 | opt.old = opt.complete; |
| 491 | |
| 492 | opt.complete = function() { |
| 493 | if ( isFunction( opt.old ) ) { |
| 494 | opt.old.call( this ); |
| 495 | } |
| 496 | |
| 497 | if ( opt.queue ) { |
| 498 | jQuery.dequeue( this, opt.queue ); |
| 499 | } |
| 500 | }; |
| 501 | |
| 502 | return opt; |
| 503 | }; |
| 504 | |
| 505 | jQuery.fn.extend( { |
| 506 | fadeTo: function( speed, to, easing, callback ) { |
| 507 | |
| 508 | // Show any hidden elements after setting opacity to 0 |
| 509 | return this.filter( isHiddenWithinTree ).css( "opacity", 0 ).show() |
| 510 | |
| 511 | // Animate to the value specified |
| 512 | .end().animate( { opacity: to }, speed, easing, callback ); |
| 513 | }, |
| 514 | animate: function( prop, speed, easing, callback ) { |
| 515 | var empty = jQuery.isEmptyObject( prop ), |
| 516 | optall = jQuery.speed( speed, easing, callback ), |
| 517 | doAnimation = function() { |
| 518 | |
| 519 | // Operate on a copy of prop so per-property easing won't be lost |
| 520 | var anim = Animation( this, jQuery.extend( {}, prop ), optall ); |
| 521 | |
| 522 | // Empty animations, or finishing resolves immediately |
| 523 | if ( empty || dataPriv.get( this, "finish" ) ) { |
| 524 | anim.stop( true ); |
| 525 | } |
| 526 | }; |
| 527 | doAnimation.finish = doAnimation; |
| 528 | |
| 529 | return empty || optall.queue === false ? |
| 530 | this.each( doAnimation ) : |
| 531 | this.queue( optall.queue, doAnimation ); |
| 532 | }, |
| 533 | stop: function( type, clearQueue, gotoEnd ) { |
| 534 | var stopQueue = function( hooks ) { |
| 535 | var stop = hooks.stop; |
| 536 | delete hooks.stop; |
| 537 | stop( gotoEnd ); |
| 538 | }; |
| 539 | |
| 540 | if ( typeof type !== "string" ) { |
| 541 | gotoEnd = clearQueue; |
| 542 | clearQueue = type; |
| 543 | type = undefined; |
| 544 | } |
| 545 | if ( clearQueue && type !== false ) { |
| 546 | this.queue( type || "fx", [] ); |
| 547 | } |
| 548 | |
| 549 | return this.each( function() { |
| 550 | var dequeue = true, |
| 551 | index = type != null && type + "queueHooks", |
| 552 | timers = jQuery.timers, |
| 553 | data = dataPriv.get( this ); |
| 554 | |
| 555 | if ( index ) { |
| 556 | if ( data[ index ] && data[ index ].stop ) { |
| 557 | stopQueue( data[ index ] ); |
| 558 | } |
| 559 | } else { |
| 560 | for ( index in data ) { |
| 561 | if ( data[ index ] && data[ index ].stop && rrun.test( index ) ) { |
| 562 | stopQueue( data[ index ] ); |
| 563 | } |
| 564 | } |
| 565 | } |
| 566 | |
| 567 | for ( index = timers.length; index--; ) { |
| 568 | if ( timers[ index ].elem === this && |
| 569 | ( type == null || timers[ index ].queue === type ) ) { |
| 570 | |
| 571 | timers[ index ].anim.stop( gotoEnd ); |
| 572 | dequeue = false; |
| 573 | timers.splice( index, 1 ); |
| 574 | } |
| 575 | } |
| 576 | |
| 577 | // Start the next in the queue if the last step wasn't forced. |
| 578 | // Timers currently will call their complete callbacks, which |
| 579 | // will dequeue but only if they were gotoEnd. |
| 580 | if ( dequeue || !gotoEnd ) { |
| 581 | jQuery.dequeue( this, type ); |
| 582 | } |
| 583 | } ); |
| 584 | }, |
| 585 | finish: function( type ) { |
| 586 | if ( type !== false ) { |
| 587 | type = type || "fx"; |
| 588 | } |
| 589 | return this.each( function() { |
| 590 | var index, |
| 591 | data = dataPriv.get( this ), |
| 592 | queue = data[ type + "queue" ], |
| 593 | hooks = data[ type + "queueHooks" ], |
| 594 | timers = jQuery.timers, |
| 595 | length = queue ? queue.length : 0; |
| 596 | |
| 597 | // Enable finishing flag on private data |
| 598 | data.finish = true; |
| 599 | |
| 600 | // Empty the queue first |
| 601 | jQuery.queue( this, type, [] ); |
| 602 | |
| 603 | if ( hooks && hooks.stop ) { |
| 604 | hooks.stop.call( this, true ); |
| 605 | } |
| 606 | |
| 607 | // Look for any active animations, and finish them |
| 608 | for ( index = timers.length; index--; ) { |
| 609 | if ( timers[ index ].elem === this && timers[ index ].queue === type ) { |
| 610 | timers[ index ].anim.stop( true ); |
| 611 | timers.splice( index, 1 ); |
| 612 | } |
| 613 | } |
| 614 | |
| 615 | // Look for any animations in the old queue and finish them |
| 616 | for ( index = 0; index < length; index++ ) { |
| 617 | if ( queue[ index ] && queue[ index ].finish ) { |
| 618 | queue[ index ].finish.call( this ); |
| 619 | } |
| 620 | } |
| 621 | |
| 622 | // Turn off finishing flag |
| 623 | delete data.finish; |
| 624 | } ); |
| 625 | } |
| 626 | } ); |
| 627 | |
| 628 | jQuery.each( [ "toggle", "show", "hide" ], function( i, name ) { |
| 629 | var cssFn = jQuery.fn[ name ]; |
| 630 | jQuery.fn[ name ] = function( speed, easing, callback ) { |
| 631 | return speed == null || typeof speed === "boolean" ? |
| 632 | cssFn.apply( this, arguments ) : |
| 633 | this.animate( genFx( name, true ), speed, easing, callback ); |
| 634 | }; |
| 635 | } ); |
| 636 | |
| 637 | // Generate shortcuts for custom animations |
| 638 | jQuery.each( { |
| 639 | slideDown: genFx( "show" ), |
| 640 | slideUp: genFx( "hide" ), |
| 641 | slideToggle: genFx( "toggle" ), |
| 642 | fadeIn: { opacity: "show" }, |
| 643 | fadeOut: { opacity: "hide" }, |
| 644 | fadeToggle: { opacity: "toggle" } |
| 645 | }, function( name, props ) { |
| 646 | jQuery.fn[ name ] = function( speed, easing, callback ) { |
| 647 | return this.animate( props, speed, easing, callback ); |
| 648 | }; |
| 649 | } ); |
| 650 | |
| 651 | jQuery.timers = []; |
| 652 | jQuery.fx.tick = function() { |
| 653 | var timer, |
| 654 | i = 0, |
| 655 | timers = jQuery.timers; |
| 656 | |
| 657 | fxNow = Date.now(); |
| 658 | |
| 659 | for ( ; i < timers.length; i++ ) { |
| 660 | timer = timers[ i ]; |
| 661 | |
| 662 | // Run the timer and safely remove it when done (allowing for external removal) |
| 663 | if ( !timer() && timers[ i ] === timer ) { |
| 664 | timers.splice( i--, 1 ); |
| 665 | } |
| 666 | } |
| 667 | |
| 668 | if ( !timers.length ) { |
| 669 | jQuery.fx.stop(); |
| 670 | } |
| 671 | fxNow = undefined; |
| 672 | }; |
| 673 | |
| 674 | jQuery.fx.timer = function( timer ) { |
| 675 | jQuery.timers.push( timer ); |
| 676 | jQuery.fx.start(); |
| 677 | }; |
| 678 | |
| 679 | jQuery.fx.interval = 13; |
| 680 | jQuery.fx.start = function() { |
| 681 | if ( inProgress ) { |
| 682 | return; |
| 683 | } |
| 684 | |
| 685 | inProgress = true; |
| 686 | schedule(); |
| 687 | }; |
| 688 | |
| 689 | jQuery.fx.stop = function() { |
| 690 | inProgress = null; |
| 691 | }; |
| 692 | |
| 693 | jQuery.fx.speeds = { |
| 694 | slow: 600, |
| 695 | fast: 200, |
| 696 | |
| 697 | // Default speed |
| 698 | _default: 400 |
| 699 | }; |
| 700 | |
| 701 | return jQuery; |
| 702 | } ); |