* jQuery UI Effects 1.13.3
* Copyright OpenJS Foundation and other contributors
* Released under the MIT license.
* https://jquery.org/license
/* eslint-disable max-len */
//>>description: Extends the internal jQuery effects. Includes morphing and easing. Required by all other effects.
/* eslint-enable max-len */
//>>docs: https://api.jqueryui.com/category/effects-core/
//>>demos: https://jqueryui.com/effect/
if ( typeof define === "function" && define.amd ) {
// AMD. Register as an anonymous module.
"./jquery-var-for-color",
"./vendor/jquery-color/jquery.color",
var dataSpace = "ui-effects-",
dataSpaceStyle = "ui-effects-style",
dataSpaceAnimated = "ui-effects-animated";
/******************************************************************************/
/****************************** CLASS ANIMATIONS ******************************/
/******************************************************************************/
var classAnimationActions = [ "add", "remove", "toggle" ],
[ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ],
$.fx.step[ prop ] = function( fx ) {
if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) {
jQuery.style( fx.elem, prop, fx.end );
function camelCase( string ) {
return string.replace( /-([\da-z])/gi, function( all, letter ) {
return letter.toUpperCase();
function getElementStyles( elem ) {
style = elem.ownerDocument.defaultView ?
elem.ownerDocument.defaultView.getComputedStyle( elem, null ) :
if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) {
if ( typeof style[ key ] === "string" ) {
styles[ camelCase( key ) ] = style[ key ];
if ( typeof style[ key ] === "string" ) {
styles[ key ] = style[ key ];
function styleDifference( oldStyle, newStyle ) {
for ( name in newStyle ) {
value = newStyle[ name ];
if ( oldStyle[ name ] !== value ) {
if ( !shorthandStyles[ name ] ) {
if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) {
$.fn.addBack = function( selector ) {
return this.add( selector == null ?
this.prevObject : this.prevObject.filter( selector )
$.effects.animateClass = function( value, duration, easing, callback ) {
var o = $.speed( duration, easing, callback );
return this.queue( function() {
var animated = $( this ),
baseClass = animated.attr( "class" ) || "",
allAnimations = o.children ? animated.find( "*" ).addBack() : animated;
// Map the animated objects to store the original styles.
allAnimations = allAnimations.map( function() {
start: getElementStyles( this )
applyClassChange = function() {
$.each( classAnimationActions, function( i, action ) {
animated[ action + "Class" ]( value[ action ] );
// Map all animated objects again - calculate new styles and diff
allAnimations = allAnimations.map( function() {
this.end = getElementStyles( this.el[ 0 ] );
this.diff = styleDifference( this.start, this.end );
animated.attr( "class", baseClass );
// Map all animated objects again - this time collecting a promise
allAnimations = allAnimations.map( function() {
opts = $.extend( {}, o, {
dfd.resolve( styleInfo );
this.el.animate( this.diff, opts );
// Once all animations have completed:
$.when.apply( $, allAnimations.get() ).done( function() {
// For each animated element,
// clear all css properties that were animated
$.each( arguments, function() {
$.each( this.diff, function( key ) {
// This is guarnteed to be there if you use jQuery.speed()
// it also handles dequeuing the next anim...
o.complete.call( animated[ 0 ] );
addClass: ( function( orig ) {
return function( classNames, speed, easing, callback ) {
$.effects.animateClass.call( this,
{ add: classNames }, speed, easing, callback ) :
orig.apply( this, arguments );
removeClass: ( function( orig ) {
return function( classNames, speed, easing, callback ) {
return arguments.length > 1 ?
$.effects.animateClass.call( this,
{ remove: classNames }, speed, easing, callback ) :
orig.apply( this, arguments );
toggleClass: ( function( orig ) {
return function( classNames, force, speed, easing, callback ) {
if ( typeof force === "boolean" || force === undefined ) {
// Without speed parameter
return orig.apply( this, arguments );
return $.effects.animateClass.call( this,
( force ? { add: classNames } : { remove: classNames } ),
speed, easing, callback );
// Without force parameter
return $.effects.animateClass.call( this,
{ toggle: classNames }, force, speed, easing );
switchClass: function( remove, add, speed, easing, callback ) {
return $.effects.animateClass.call( this, {
}, speed, easing, callback );
/******************************************************************************/
/*********************************** EFFECTS **********************************/
/******************************************************************************/
if ( $.expr && $.expr.pseudos && $.expr.pseudos.animated ) {
$.expr.pseudos.animated = ( function( orig ) {
return function( elem ) {
return !!$( elem ).data( dataSpaceAnimated ) || orig( elem );
} )( $.expr.pseudos.animated );
if ( $.uiBackCompat !== false ) {
// Saves a set of properties in a data storage
save: function( element, set ) {
var i = 0, length = set.length;
for ( ; i < length; i++ ) {
if ( set[ i ] !== null ) {
element.data( dataSpace + set[ i ], element[ 0 ].style[ set[ i ] ] );
// Restores a set of previously saved properties from a data storage
restore: function( element, set ) {
var val, i = 0, length = set.length;
for ( ; i < length; i++ ) {
if ( set[ i ] !== null ) {
val = element.data( dataSpace + set[ i ] );
element.css( set[ i ], val );
setMode: function( el, mode ) {
if ( mode === "toggle" ) {
mode = el.is( ":hidden" ) ? "show" : "hide";
// Wraps the element around a wrapper that copies position properties
createWrapper: function( element ) {
// If the element is already wrapped, return it
if ( element.parent().is( ".ui-effects-wrapper" ) ) {
width: element.outerWidth( true ),
height: element.outerHeight( true ),
"float": element.css( "float" )
wrapper = $( "<div></div>" )
.addClass( "ui-effects-wrapper" )
background: "transparent",
// Store the size in case width/height are defined in % - Fixes #5245
active = document.activeElement;
// Firefox incorrectly exposes anonymous content
// https://bugzilla.mozilla.org/show_bug.cgi?id=561664
// eslint-disable-next-line no-unused-expressions
// Fixes #7595 - Elements lose focus when wrapped.
if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
$( active ).trigger( "focus" );
// Hotfix for jQuery 1.4 since some change in wrap() seems to actually
// lose the reference to the wrapped element
wrapper = element.parent();
// Transfer positioning properties to the wrapper
if ( element.css( "position" ) === "static" ) {
wrapper.css( { position: "relative" } );
element.css( { position: "relative" } );
position: element.css( "position" ),
zIndex: element.css( "z-index" )
$.each( [ "top", "left", "bottom", "right" ], function( i, pos ) {
props[ pos ] = element.css( pos );
if ( isNaN( parseInt( props[ pos ], 10 ) ) ) {
return wrapper.css( props ).show();
removeWrapper: function( element ) {
var active = document.activeElement;
if ( element.parent().is( ".ui-effects-wrapper" ) ) {
element.parent().replaceWith( element );
// Fixes #7595 - Elements lose focus when wrapped.
if ( element[ 0 ] === active || $.contains( element[ 0 ], active ) ) {
$( active ).trigger( "focus" );
define: function( name, mode, effect ) {
$.effects.effect[ name ] = effect;
$.effects.effect[ name ].mode = mode;
scaledDimensions: function( element, percent, direction ) {
var x = direction !== "horizontal" ? ( ( percent || 100 ) / 100 ) : 1,
y = direction !== "vertical" ? ( ( percent || 100 ) / 100 ) : 1;
height: element.height() * y,
width: element.width() * x,
outerHeight: element.outerHeight() * y,
outerWidth: element.outerWidth() * x
clipToBox: function( animation ) {
width: animation.clip.right - animation.clip.left,
height: animation.clip.bottom - animation.clip.top,
left: animation.clip.left,
// Injects recently queued functions to be first in line (after "inprogress")
unshift: function( element, queueLength, count ) {
var queue = element.queue();
queue.splice.apply( queue,
[ 1, 0 ].concat( queue.splice( queueLength, count ) ) );
saveStyle: function( element ) {
element.data( dataSpaceStyle, element[ 0 ].style.cssText );
restoreStyle: function( element ) {
element[ 0 ].style.cssText = element.data( dataSpaceStyle ) || "";
element.removeData( dataSpaceStyle );
mode: function( element, mode ) {
var hidden = element.is( ":hidden" );
if ( mode === "toggle" ) {
mode = hidden ? "show" : "hide";
if ( hidden ? mode === "hide" : mode === "show" ) {
// Translates a [top,left] array into a baseline value
getBaseline: function( origin, original ) {
y = origin[ 0 ] / original.height;