return extra === true || isFinite( num ) ? num || 0 : val;
jQuery.each( [ "height", "width" ], function( _i, dimension ) {
jQuery.cssHooks[ dimension ] = {
get: function( elem, computed, extra ) {
// Certain elements can have dimension info if we invisibly show them
// but it must have a current display style that would benefit
return rdisplayswap.test( jQuery.css( elem, "display" ) ) &&
// Table columns in Safari have non-zero offsetWidth & zero
// getBoundingClientRect().width unless display is changed.
// Running getBoundingClientRect on a disconnected node
// in IE throws an error.
( !elem.getClientRects().length || !elem.getBoundingClientRect().width ) ?
swap( elem, cssShow, function() {
return getWidthOrHeight( elem, dimension, extra );
getWidthOrHeight( elem, dimension, extra );
set: function( elem, value, extra ) {
styles = getStyles( elem ),
// Only read styles.position if the test has a chance to fail
// to avoid forcing a reflow.
scrollboxSizeBuggy = !support.scrollboxSize() &&
styles.position === "absolute",
// To avoid forcing a reflow, only fetch boxSizing if we need it (gh-3991)
boxSizingNeeded = scrollboxSizeBuggy || extra,
isBorderBox = boxSizingNeeded &&
jQuery.css( elem, "boxSizing", false, styles ) === "border-box",
// Account for unreliable border-box dimensions by comparing offset* to computed and
// faking a content-box to get border and padding (gh-3699)
if ( isBorderBox && scrollboxSizeBuggy ) {
elem[ "offset" + dimension[ 0 ].toUpperCase() + dimension.slice( 1 ) ] -
parseFloat( styles[ dimension ] ) -
boxModelAdjustment( elem, dimension, "border", false, styles ) -
// Convert to pixels if value adjustment is needed
if ( subtract && ( matches = rcssNum.exec( value ) ) &&
( matches[ 3 ] || "px" ) !== "px" ) {
elem.style[ dimension ] = value;
value = jQuery.css( elem, dimension );
return setPositiveNumber( elem, value, subtract );
jQuery.cssHooks.marginLeft = addGetHookIf( support.reliableMarginLeft,
function( elem, computed ) {
return ( parseFloat( curCSS( elem, "marginLeft" ) ) ||
elem.getBoundingClientRect().left -
swap( elem, { marginLeft: 0 }, function() {
return elem.getBoundingClientRect().left;
// These hooks are used by animate to expand properties
}, function( prefix, suffix ) {
jQuery.cssHooks[ prefix + suffix ] = {
expand: function( value ) {
// Assumes a single number if not a string
parts = typeof value === "string" ? value.split( " " ) : [ value ];
expanded[ prefix + cssExpand[ i ] + suffix ] =
parts[ i ] || parts[ i - 2 ] || parts[ 0 ];
if ( prefix !== "margin" ) {
jQuery.cssHooks[ prefix + suffix ].set = setPositiveNumber;
css: function( name, value ) {
return access( this, function( elem, name, value ) {
if ( Array.isArray( name ) ) {
styles = getStyles( elem );
map[ name[ i ] ] = jQuery.css( elem, name[ i ], false, styles );
return value !== undefined ?
jQuery.style( elem, name, value ) :
jQuery.css( elem, name );
}, name, value, arguments.length > 1 );
function Tween( elem, options, prop, end, easing ) {
return new Tween.prototype.init( elem, options, prop, end, easing );
init: function( elem, options, prop, end, easing, unit ) {
this.easing = easing || jQuery.easing._default;
this.start = this.now = this.cur();
this.unit = unit || ( jQuery.cssNumber[ prop ] ? "" : "px" );
var hooks = Tween.propHooks[ this.prop ];
return hooks && hooks.get ?
Tween.propHooks._default.get( this );
run: function( percent ) {
hooks = Tween.propHooks[ this.prop ];
if ( this.options.duration ) {
this.pos = eased = jQuery.easing[ this.easing ](
percent, this.options.duration * percent, 0, 1, this.options.duration
this.pos = eased = percent;
this.now = ( this.end - this.start ) * eased + this.start;
if ( this.options.step ) {
this.options.step.call( this.elem, this.now, this );
if ( hooks && hooks.set ) {
Tween.propHooks._default.set( this );
Tween.prototype.init.prototype = Tween.prototype;
// Use a property on the element directly when it is not a DOM element,
// or when there is no matching style property that exists.
if ( tween.elem.nodeType !== 1 ||
tween.elem[ tween.prop ] != null && tween.elem.style[ tween.prop ] == null ) {
return tween.elem[ tween.prop ];
// Passing an empty string as a 3rd parameter to .css will automatically
// attempt a parseFloat and fallback to a string if the parse fails.
// Simple values such as "10px" are parsed to Float;
// complex values such as "rotate(1rad)" are returned as-is.
result = jQuery.css( tween.elem, tween.prop, "" );
// Empty strings, null, undefined and "auto" are converted to 0.
return !result || result === "auto" ? 0 : result;
// Use step hook for back compat.
// Use cssHook if its there.
// Use .style if available and use plain properties where available.
if ( jQuery.fx.step[ tween.prop ] ) {
jQuery.fx.step[ tween.prop ]( tween );
} else if ( tween.elem.nodeType === 1 && (
jQuery.cssHooks[ tween.prop ] ||
tween.elem.style[ finalPropName( tween.prop ) ] != null ) ) {
jQuery.style( tween.elem, tween.prop, tween.now + tween.unit );
tween.elem[ tween.prop ] = tween.now;
// Panic based approach to setting things on disconnected nodes
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = {
if ( tween.elem.nodeType && tween.elem.parentNode ) {
tween.elem[ tween.prop ] = tween.now;
return 0.5 - Math.cos( p * Math.PI ) / 2;
jQuery.fx = Tween.prototype.init;
// Back compat <1.8 extension point
rfxtypes = /^(?:toggle|show|hide)$/,
if ( document.hidden === false && window.requestAnimationFrame ) {
window.requestAnimationFrame( schedule );
window.setTimeout( schedule, jQuery.fx.interval );
// Animations created synchronously will run synchronously
window.setTimeout( function() {
return ( fxNow = Date.now() );
// Generate parameters to create a standard animation
function genFx( type, includeWidth ) {
attrs = { height: type };
// If we include width, step value is 1 to do all cssExpand values,
// otherwise step value is 2 to skip over Left and Right
includeWidth = includeWidth ? 1 : 0;
for ( ; i < 4; i += 2 - includeWidth ) {
attrs[ "margin" + which ] = attrs[ "padding" + which ] = type;
attrs.opacity = attrs.width = type;
function createTween( value, prop, animation ) {
collection = ( Animation.tweeners[ prop ] || [] ).concat( Animation.tweeners[ "*" ] ),
length = collection.length;
for ( ; index < length; index++ ) {
if ( ( tween = collection[ index ].call( animation, prop, value ) ) ) {
// We're done with this property
function defaultPrefilter( elem, props, opts ) {
var prop, value, toggle, hooks, oldfire, propTween, restoreDisplay, display,
isBox = "width" in props || "height" in props,
hidden = elem.nodeType && isHiddenWithinTree( elem ),
dataShow = dataPriv.get( elem, "fxshow" );
// Queue-skipping animations hijack the fx hooks
hooks = jQuery._queueHooks( elem, "fx" );
if ( hooks.unqueued == null ) {
oldfire = hooks.empty.fire;
hooks.empty.fire = function() {
anim.always( function() {
// Ensure the complete handler is called before this completes
anim.always( function() {
if ( !jQuery.queue( elem, "fx" ).length ) {
// Detect show/hide animations
if ( rfxtypes.test( value ) ) {
toggle = toggle || value === "toggle";
if ( value === ( hidden ? "hide" : "show" ) ) {
// Pretend to be hidden if this is a "show" and
// there is still data from a stopped show/hide
if ( value === "show" && dataShow && dataShow[ prop ] !== undefined ) {
// Ignore all other no-op show/hide data
orig[ prop ] = dataShow && dataShow[ prop ] || jQuery.style( elem, prop );
// Bail out if this is a no-op like .hide().hide()
propTween = !jQuery.isEmptyObject( props );
if ( !propTween && jQuery.isEmptyObject( orig ) ) {
// Restrict "overflow" and "display" styles during box animations
if ( isBox && elem.nodeType === 1 ) {
// Support: IE <=9 - 11, Edge 12 - 15
// Record all 3 overflow attributes because IE does not infer the shorthand
// from identically-valued overflowX and overflowY and Edge just mirrors
// the overflowX value there.
opts.overflow = [ style.overflow, style.overflowX, style.overflowY ];
// Identify a display type, preferring old show/hide data over the CSS cascade
restoreDisplay = dataShow && dataShow.display;
if ( restoreDisplay == null ) {
restoreDisplay = dataPriv.get( elem, "display" );
display = jQuery.css( elem, "display" );
if ( display === "none" ) {
display = restoreDisplay;
// Get nonempty value(s) by temporarily forcing visibility
showHide( [ elem ], true );
restoreDisplay = elem.style.display || restoreDisplay;
display = jQuery.css( elem, "display" );
// Animate inline elements as inline-block
if ( display === "inline" || display === "inline-block" && restoreDisplay != null ) {
if ( jQuery.css( elem, "float" ) === "none" ) {
// Restore the original display value at the end of pure show/hide animations
style.display = restoreDisplay;
if ( restoreDisplay == null ) {
restoreDisplay = display === "none" ? "" : display;
style.display = "inline-block";
style.overflow = "hidden";
anim.always( function() {
style.overflow = opts.overflow[ 0 ];
style.overflowX = opts.overflow[ 1 ];
style.overflowY = opts.overflow[ 2 ];
// Implement show/hide animations
// General show/hide setup for this element animation
if ( "hidden" in dataShow ) {
hidden = dataShow.hidden;
dataShow = dataPriv.access( elem, "fxshow", { display: restoreDisplay } );
// Store hidden/visible for toggle so `.stop().toggle()` "reverses"
dataShow.hidden = !hidden;
// Show elements before animating them
showHide( [ elem ], true );
/* eslint-disable no-loop-func */
/* eslint-enable no-loop-func */
// The final step of a "hide" animation is actually hiding the element
dataPriv.remove( elem, "fxshow" );
jQuery.style( elem, prop, orig[ prop ] );
propTween = createTween( hidden ? dataShow[ prop ] : 0, prop, anim );
if ( !( prop in dataShow ) ) {
dataShow[ prop ] = propTween.start;
propTween.end = propTween.start;
function propFilter( props, specialEasing ) {
var index, name, easing, value, hooks;
// camelCase, specialEasing and expand cssHook pass