" )[ 0 ], // colors = jQuery.Color.names colors, // local aliases of functions called often each = jQuery.each; // determine rgba support immediately supportElem.style.cssText = "background-color:rgba(1,1,1,.5)"; support.rgba = supportElem.style.backgroundColor.indexOf( "rgba" ) > -1; // define cache name and alpha properties // for rgba and hsla spaces each( spaces, function( spaceName, space ) { space.cache = "_" + spaceName; space.props.alpha = { idx: 3, type: "percent", def: 1 }; } ); // Populate the class2type map jQuery.each( "Boolean Number String Function Array Date RegExp Object Error Symbol".split( " " ), function( _i, name ) { class2type[ "[object " + name + "]" ] = name.toLowerCase(); } ); function getType( obj ) { if ( obj == null ) { return obj + ""; } return typeof obj === "object" ? class2type[ toString.call( obj ) ] || "object" : typeof obj; } function clamp( value, prop, allowEmpty ) { var type = propTypes[ prop.type ] || {}; if ( value == null ) { return ( allowEmpty || !prop.def ) ? null : prop.def; } // ~~ is an short way of doing floor for positive numbers value = type.floor ? ~~value : parseFloat( value ); // IE will pass in empty strings as value for alpha, // which will hit this case if ( isNaN( value ) ) { return prop.def; } if ( type.mod ) { // we add mod before modding to make sure that negatives values // get converted properly: -10 -> 350 return ( value + type.mod ) % type.mod; } // for now all property types without mod have min and max return Math.min( type.max, Math.max( 0, value ) ); } function stringParse( string ) { var inst = color(), rgba = inst._rgba = []; string = string.toLowerCase(); each( stringParsers, function( _i, parser ) { var parsed, match = parser.re.exec( string ), values = match && parser.parse( match ), spaceName = parser.space || "rgba"; if ( values ) { parsed = inst[ spaceName ]( values ); // if this was an rgba parse the assignment might happen twice // oh well.... inst[ spaces[ spaceName ].cache ] = parsed[ spaces[ spaceName ].cache ]; rgba = inst._rgba = parsed._rgba; // exit each( stringParsers ) here because we matched return false; } } ); // Found a stringParser that handled it if ( rgba.length ) { // if this came from a parsed string, force "transparent" when alpha is 0 // chrome, (and maybe others) return "transparent" as rgba(0,0,0,0) if ( rgba.join() === "0,0,0,0" ) { jQuery.extend( rgba, colors.transparent ); } return inst; } // named colors return colors[ string ]; } color.fn = jQuery.extend( color.prototype, { parse: function( red, green, blue, alpha ) { if ( red === undefined ) { this._rgba = [ null, null, null, null ]; return this; } if ( red.jquery || red.nodeType ) { red = jQuery( red ).css( green ); green = undefined; } var inst = this, type = getType( red ), rgba = this._rgba = []; // more than 1 argument specified - assume ( red, green, blue, alpha ) if ( green !== undefined ) { red = [ red, green, blue, alpha ]; type = "array"; } if ( type === "string" ) { return this.parse( stringParse( red ) || colors._default ); } if ( type === "array" ) { each( spaces.rgba.props, function( _key, prop ) { rgba[ prop.idx ] = clamp( red[ prop.idx ], prop ); } ); return this; } if ( type === "object" ) { if ( red instanceof color ) { each( spaces, function( _spaceName, space ) { if ( red[ space.cache ] ) { inst[ space.cache ] = red[ space.cache ].slice(); } } ); } else { each( spaces, function( _spaceName, space ) { var cache = space.cache; each( space.props, function( key, prop ) { // if the cache doesn't exist, and we know how to convert if ( !inst[ cache ] && space.to ) { // if the value was null, we don't need to copy it // if the key was alpha, we don't need to copy it either if ( key === "alpha" || red[ key ] == null ) { return; } inst[ cache ] = space.to( inst._rgba ); } // this is the only case where we allow nulls for ALL properties. // call clamp with alwaysAllowEmpty inst[ cache ][ prop.idx ] = clamp( red[ key ], prop, true ); } ); // everything defined but alpha? if ( inst[ cache ] && jQuery.inArray( null, inst[ cache ].slice( 0, 3 ) ) < 0 ) { // use the default of 1 if ( inst[ cache ][ 3 ] == null ) { inst[ cache ][ 3 ] = 1; } if ( space.from ) { inst._rgba = space.from( inst[ cache ] ); } } } ); } return this; } }, is: function( compare ) { var is = color( compare ), same = true, inst = this; each( spaces, function( _, space ) { var localCache, isCache = is[ space.cache ]; if ( isCache ) { localCache = inst[ space.cache ] || space.to && space.to( inst._rgba ) || []; each( space.props, function( _, prop ) { if ( isCache[ prop.idx ] != null ) { same = ( isCache[ prop.idx ] === localCache[ prop.idx ] ); return same; } } ); } return same; } ); return same; }, _space: function() { var used = [], inst = this; each( spaces, function( spaceName, space ) { if ( inst[ space.cache ] ) { used.push( spaceName ); } } ); return used.pop(); }, transition: function( other, distance ) { var end = color( other ), spaceName = end._space(), space = spaces[ spaceName ], startColor = this.alpha() === 0 ? color( "transparent" ) : this, start = startColor[ space.cache ] || space.to( startColor._rgba ), result = start.slice(); end = end[ space.cache ]; each( space.props, function( _key, prop ) { var index = prop.idx, startValue = start[ index ], endValue = end[ index ], type = propTypes[ prop.type ] || {}; // if null, don't override start value if ( endValue === null ) { return; } // if null - use end if ( startValue === null ) { result[ index ] = endValue; } else { if ( type.mod ) { if ( endValue - startValue > type.mod / 2 ) { startValue += type.mod; } else if ( startValue - endValue > type.mod / 2 ) { startValue -= type.mod; } } result[ index ] = clamp( ( endValue - startValue ) * distance + startValue, prop ); } } ); return this[ spaceName ]( result ); }, blend: function( opaque ) { // if we are already opaque - return ourself if ( this._rgba[ 3 ] === 1 ) { return this; } var rgb = this._rgba.slice(), a = rgb.pop(), blend = color( opaque )._rgba; return color( jQuery.map( rgb, function( v, i ) { return ( 1 - a ) * blend[ i ] + a * v; } ) ); }, toRgbaString: function() { var prefix = "rgba(", rgba = jQuery.map( this._rgba, function( v, i ) { if ( v != null ) { return v; } return i > 2 ? 1 : 0; } ); if ( rgba[ 3 ] === 1 ) { rgba.pop(); prefix = "rgb("; } return prefix + rgba.join() + ")"; }, toHslaString: function() { var prefix = "hsla(", hsla = jQuery.map( this.hsla(), function( v, i ) { if ( v == null ) { v = i > 2 ? 1 : 0; } // catch 1 and 2 if ( i && i < 3 ) { v = Math.round( v * 100 ) + "%"; } return v; } ); if ( hsla[ 3 ] === 1 ) { hsla.pop(); prefix = "hsl("; } return prefix + hsla.join() + ")"; }, toHexString: function( includeAlpha ) { var rgba = this._rgba.slice(), alpha = rgba.pop(); if ( includeAlpha ) { rgba.push( ~~( alpha * 255 ) ); } return "#" + jQuery.map( rgba, function( v ) { // default to 0 when nulls exist v = ( v || 0 ).toString( 16 ); return v.length === 1 ? "0" + v : v; } ).join( "" ); }, toString: function() { return this._rgba[ 3 ] === 0 ? "transparent" : this.toRgbaString(); } } ); color.fn.parse.prototype = color.fn; // hsla conversions adapted from: // https://code.google.com/p/maashaack/source/browse/packages/graphics/trunk/src/graphics/colors/HUE2RGB.as?r=5021 function hue2rgb( p, q, h ) { h = ( h + 1 ) % 1; if ( h * 6 < 1 ) { return p + ( q - p ) * h * 6; } if ( h * 2 < 1 ) { return q; } if ( h * 3 < 2 ) { return p + ( q - p ) * ( ( 2 / 3 ) - h ) * 6; } return p; } spaces.hsla.to = function( rgba ) { if ( rgba[ 0 ] == null || rgba[ 1 ] == null || rgba[ 2 ] == null ) { return [ null, null, null, rgba[ 3 ] ]; } var r = rgba[ 0 ] / 255, g = rgba[ 1 ] / 255, b = rgba[ 2 ] / 255, a = rgba[ 3 ], max = Math.max( r, g, b ), min = Math.min( r, g, b ), diff = max - min, add = max + min, l = add * 0.5, h, s; if ( min === max ) { h = 0; } else if ( r === max ) { h = ( 60 * ( g - b ) / diff ) + 360; } else if ( g === max ) { h = ( 60 * ( b - r ) / diff ) + 120; } else { h = ( 60 * ( r - g ) / diff ) + 240; } // chroma (diff) == 0 means greyscale which, by definition, saturation = 0% // otherwise, saturation is based on the ratio of chroma (diff) to lightness (add) if ( diff === 0 ) { s = 0; } else if ( l <= 0.5 ) { s = diff / add; } else { s = diff / ( 2 - add ); } return [ Math.round( h ) % 360, s, l, a == null ? 1 : a ]; }; spaces.hsla.from = function( hsla ) { if ( hsla[ 0 ] == null || hsla[ 1 ] == null || hsla[ 2 ] == null ) { return [ null, null, null, hsla[ 3 ] ]; } var h = hsla[ 0 ] / 360, s = hsla[ 1 ], l = hsla[ 2 ], a = hsla[ 3 ], q = l <= 0.5 ? l * ( 1 + s ) : l + s - l * s, p = 2 * l - q; return [ Math.round( hue2rgb( p, q, h + ( 1 / 3 ) ) * 255 ), Math.round( hue2rgb( p, q, h ) * 255 ), Math.round( hue2rgb( p, q, h - ( 1 / 3 ) ) * 255 ), a ]; }; each( spaces, function( spaceName, space ) { var props = space.props, cache = space.cache, to = space.to, from = space.from; // makes rgba() and hsla() color.fn[ spaceName ] = function( value ) { // generate a cache for this space if it doesn't exist if ( to && !this[ cache ] ) { this[ cache ] = to( this._rgba ); } if ( value === undefined ) { return this[ cache ].slice(); } var ret, type = getType( value ), arr = ( type === "array" || type === "object" ) ? value : arguments, local = this[ cache ].slice(); each( props, function( key, prop ) { var val = arr[ type === "object" ? key : prop.idx ]; if ( val == null ) { val = local[ prop.idx ]; } local[ prop.idx ] = clamp( val, prop ); } ); if ( from ) { ret = color( from( local ) ); ret[ cache ] = local; return ret; } else { return color( local ); } }; // makes red() green() blue() alpha() hue() saturation() lightness() each( props, function( key, prop ) { // alpha is included in more than one space if ( color.fn[ key ] ) { return; } color.fn[ key ] = function( value ) { var local, cur, match, fn, vtype = getType( value ); if ( key === "alpha" ) { fn = this._hsla ? "hsla" : "rgba"; } else { fn = spaceName; } local = this[ fn ](); cur = local[ prop.idx ]; if ( vtype === "undefined" ) { return cur; } if ( vtype === "function" ) { value = value.call( this, cur ); vtype = getType( value ); } if ( value == null && prop.empty ) { return this; } if ( vtype === "string" ) { match = rplusequals.exec( value ); if ( match ) { value = cur + parseFloat( match[ 2 ] ) * ( match[ 1 ] === "+" ? 1 : -1 ); } } local[ prop.idx ] = value; return this[ fn ]( local ); }; } ); } ); // add cssHook and .fx.step function for each named hook. // accept a space separated string of properties color.hook = function( hook ) { var hooks = hook.split( " " ); each( hooks, function( _i, hook ) { jQuery.cssHooks[ hook ] = { set: function( elem, value ) { var parsed, curElem, backgroundColor = ""; if ( value !== "transparent" && ( getType( value ) !== "string" || ( parsed = stringParse( value ) ) ) ) { value = color( parsed || value ); if ( !support.rgba && value._rgba[ 3 ] !== 1 ) { curElem = hook === "backgroundColor" ? elem.parentNode : elem; while ( ( backgroundColor === "" || backgroundColor === "transparent" ) && curElem && curElem.style ) { try { backgroundColor = jQuery.css( curElem, "backgroundColor" ); curElem = curElem.parentNode; } catch ( e ) { } } value = value.blend( backgroundColor && backgroundColor !== "transparent" ? backgroundColor : "_default" ); } value = value.toRgbaString(); } try { elem.style[ hook ] = value; } catch ( e ) { // wrapped to prevent IE from throwing errors on "invalid" values like 'auto' or 'inherit' } } }; jQuery.fx.step[ hook ] = function( fx ) { if ( !fx.colorInit ) { fx.start = color( fx.elem, hook ); fx.end = color( fx.end ); fx.colorInit = true; } jQuery.cssHooks[ hook ].set( fx.elem, fx.start.transition( fx.end, fx.pos ) ); }; } ); }; color.hook( stepHooks ); jQuery.cssHooks.borderColor = { expand: function( value ) { var expanded = {}; each( [ "Top", "Right", "Bottom", "Left" ], function( _i, part ) { expanded[ "border" + part + "Color" ] = value; } ); return expanded; } }; // Basic color names only. // Usage of any of the other color names requires adding yourself or including // jquery.color.svg-names.js. colors = jQuery.Color.names = { // 4.1. Basic color keywords aqua: "#00ffff", black: "#000000", blue: "#0000ff", fuchsia: "#ff00ff", gray: "#808080", green: "#008000", lime: "#00ff00", maroon: "#800000", navy: "#000080", olive: "#808000", purple: "#800080", red: "#ff0000", silver: "#c0c0c0", teal: "#008080", white: "#ffffff", yellow: "#ffff00", // 4.2.3. "transparent" color keyword transparent: [ null, null, null, 0 ], _default: "#ffffff" }; var dataSpace = "ui-effects-", dataSpaceStyle = "ui-effects-style", dataSpaceAnimated = "ui-effects-animated"; $.effects = { effect: {} }; /******************************************************************************/ /****************************** CLASS ANIMATIONS ******************************/ /******************************************************************************/ ( function() { var classAnimationActions = [ "add", "remove", "toggle" ], shorthandStyles = { border: 1, borderBottom: 1, borderColor: 1, borderLeft: 1, borderRight: 1, borderTop: 1, borderWidth: 1, margin: 1, padding: 1 }; $.each( [ "borderLeftStyle", "borderRightStyle", "borderBottomStyle", "borderTopStyle" ], function( _, prop ) { $.fx.step[ prop ] = function( fx ) { if ( fx.end !== "none" && !fx.setAttr || fx.pos === 1 && !fx.setAttr ) { jQuery.style( fx.elem, prop, fx.end ); fx.setAttr = true; } }; } ); function camelCase( string ) { return string.replace( /-([\da-z])/gi, function( all, letter ) { return letter.toUpperCase(); } ); } function getElementStyles( elem ) { var key, len, style = elem.ownerDocument.defaultView ? elem.ownerDocument.defaultView.getComputedStyle( elem, null ) : elem.currentStyle, styles = {}; if ( style && style.length && style[ 0 ] && style[ style[ 0 ] ] ) { len = style.length; while ( len-- ) { key = style[ len ]; if ( typeof style[ key ] === "string" ) { styles[ camelCase( key ) ] = style[ key ]; } } // Support: Opera, IE <9 } else { for ( key in style ) { if ( typeof style[ key ] === "string" ) { styles[ key ] = style[ key ]; } } } return styles; } function styleDifference( oldStyle, newStyle ) { var diff = {}, name, value; for ( name in newStyle ) { value = newStyle[ name ]; if ( oldStyle[ name ] !== value ) { if ( !shorthandStyles[ name ] ) { if ( $.fx.step[ name ] || !isNaN( parseFloat( value ) ) ) { diff[ name ] = value; } } } } return diff; } // Support: jQuery <1.8 if ( !$.fn.addBack ) { $.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" ) || "", applyClassChange, allAnimations = o.children ? animated.find( "*" ).addBack() : animated; // Map the animated objects to store the original styles. allAnimations = allAnimations.map( function() { var el = $( this ); return { el: el, start: getElementStyles( this ) }; } ); // Apply class change applyClassChange = function() { $.each( classAnimationActions, function( i, action ) { if ( value[ action ] ) { animated[ action + "Class" ]( value[ action ] ); } } ); }; applyClassChange(); // 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 ); return this; } ); // Apply original class animated.attr( "class", baseClass ); // Map all animated objects again - this time collecting a promise allAnimations = allAnimations.map( function() { var styleInfo = this, dfd = $.Deferred(), opts = $.extend( {}, o, { queue: false, complete: function() { dfd.resolve( styleInfo ); } } ); this.el.animate( this.diff, opts ); return dfd.promise(); } ); // Once all animations have completed: $.when.apply( $, allAnimations.get() ).done( function() { // Set the final class applyClassChange(); // For each animated element, // clear all css properties that were animated $.each( arguments, function() { var el = this.el; $.each( this.diff, function( key ) { el.css( key, "" ); } ); } ); // This is guarnteed to be there if you use jQuery.speed() // it also handles dequeuing the next anim... o.complete.call( animated[ 0 ] ); } ); } ); }; $.fn.extend( { addClass: ( function( orig ) { return function( classNames, speed, easing, callback ) { return speed ? $.effects.animateClass.call( this, { add: classNames }, speed, easing, callback ) : orig.apply( this, arguments ); }; } )( $.fn.addClass ), 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 ); }; } )( $.fn.removeClass ), toggleClass: ( function( orig ) { return function( classNames, force, speed, easing, callback ) { if ( typeof force === "boolean" || force === undefined ) { if ( !speed ) { // Without speed parameter return orig.apply( this, arguments ); } else { return $.effects.animateClass.call( this, ( force ? { add: classNames } : { remove: classNames } ), speed, easing, callback ); } } else { // Without force parameter return $.effects.animateClass.call( this, { toggle: classNames }, force, speed, easing ); } }; } )( $.fn.toggleClass ), switchClass: function( remove, add, speed, easing, callback ) { return $.effects.animateClass.call( this, { add: add, remove: remove }, speed, easing, callback ); } } ); } )(); /******************************************************************************/ /*********************************** EFFECTS **********************************/ /******************************************************************************/ ( function() { 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 ) { $.extend( $.effects, { // 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"; } return mode; }, // 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" ) ) { return element.parent(); } // Wrap the element var props = { width: element.outerWidth( true ), height: element.outerHeight( true ), "float": element.css( "float" ) }, wrapper = $( "