|
/* |
|
* jQuery UI Effects @VERSION |
|
* |
|
* Copyright 2011, AUTHORS.txt (http://jqueryui.com/about) |
|
* Dual licensed under the MIT or GPL Version 2 licenses. |
|
* http://jquery.org/license |
|
* |
|
* http://docs.jquery.com/UI/Effects/ |
|
*/ |
|
;jQuery.effects || (function($, undefined) { |
|
|
|
$.effects = {}; |
|
|
|
|
|
|
|
/******************************************************************************/ |
|
/****************************** COLOR ANIMATIONS ******************************/ |
|
/******************************************************************************/ |
|
|
|
// override the animation for color styles |
|
$.each(['backgroundColor', 'borderBottomColor', 'borderLeftColor', |
|
'borderRightColor', 'borderTopColor', 'borderColor', 'color', 'outlineColor'], |
|
function(i, attr) { |
|
$.fx.step[attr] = function(fx) { |
|
if (!fx.colorInit) { |
|
fx.start = getColor(fx.elem, attr); |
|
fx.end = getRGB(fx.end); |
|
fx.colorInit = true; |
|
} |
|
|
|
fx.elem.style[attr] = 'rgb(' + |
|
Math.max(Math.min(parseInt((fx.pos * (fx.end[0] - fx.start[0])) + fx.start[0], 10), 255), 0) + ',' + |
|
Math.max(Math.min(parseInt((fx.pos * (fx.end[1] - fx.start[1])) + fx.start[1], 10), 255), 0) + ',' + |
|
Math.max(Math.min(parseInt((fx.pos * (fx.end[2] - fx.start[2])) + fx.start[2], 10), 255), 0) + ')'; |
|
}; |
|
}); |
|
|
|
// Color Conversion functions from highlightFade |
|
// By Blair Mitchelmore |
|
// http://jquery.offput.ca/highlightFade/ |
|
|
|
// Parse strings looking for color tuples [255,255,255] |
|
function getRGB(color) { |
|
var result; |
|
|
|
// Check if we're already dealing with an array of colors |
|
if ( color && color.constructor == Array && color.length == 3 ) |
|
return color; |
|
|
|
// Look for rgb(num,num,num) |
|
if (result = /rgb\(\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*,\s*([0-9]{1,3})\s*\)/.exec(color)) |
|
return [parseInt(result[1],10), parseInt(result[2],10), parseInt(result[3],10)]; |
|
|
|
// Look for rgb(num%,num%,num%) |
|
if (result = /rgb\(\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*,\s*([0-9]+(?:\.[0-9]+)?)\%\s*\)/.exec(color)) |
|
return [parseFloat(result[1])*2.55, parseFloat(result[2])*2.55, parseFloat(result[3])*2.55]; |
|
|
|
// Look for #a0b1c2 |
|
if (result = /#([a-fA-F0-9]{2})([a-fA-F0-9]{2})([a-fA-F0-9]{2})/.exec(color)) |
|
return [parseInt(result[1],16), parseInt(result[2],16), parseInt(result[3],16)]; |
|
|
|
// Look for #fff |
|
if (result = /#([a-fA-F0-9])([a-fA-F0-9])([a-fA-F0-9])/.exec(color)) |
|
return [parseInt(result[1]+result[1],16), parseInt(result[2]+result[2],16), parseInt(result[3]+result[3],16)]; |
|
|
|
// Look for rgba(0, 0, 0, 0) == transparent in Safari 3 |
|
if (result = /rgba\(0, 0, 0, 0\)/.exec(color)) |
|
return colors['transparent']; |
|
|
|
// Otherwise, we're most likely dealing with a named color |
|
return colors[$.trim(color).toLowerCase()]; |
|
} |
|
|
|
function getColor(elem, attr) { |
|
var color; |
|
|
|
do { |
|
color = $.curCSS(elem, attr); |
|
|
|
// Keep going until we find an element that has color, or we hit the body |
|
if ( color != '' && color != 'transparent' || $.nodeName(elem, "body") ) |
|
break; |
|
|
|
attr = "backgroundColor"; |
|
} while ( elem = elem.parentNode ); |
|
|
|
return getRGB(color); |
|
}; |
|
|
|
// Some named colors to work with |
|
// From Interface by Stefan Petre |
|
// http://interface.eyecon.ro/ |
|
|
|
var colors = { |
|
aqua:[0,255,255], |
|
azure:[240,255,255], |
|
beige:[245,245,220], |
|
black:[0,0,0], |
|
blue:[0,0,255], |
|
brown:[165,42,42], |
|
cyan:[0,255,255], |
|
darkblue:[0,0,139], |
|
darkcyan:[0,139,139], |
|
darkgrey:[169,169,169], |
|
darkgreen:[0,100,0], |
|
darkkhaki:[189,183,107], |
|
darkmagenta:[139,0,139], |
|
darkolivegreen:[85,107,47], |
|
darkorange:[255,140,0], |
|
darkorchid:[153,50,204], |
|
darkred:[139,0,0], |
|
darksalmon:[233,150,122], |
|
darkviolet:[148,0,211], |
|
fuchsia:[255,0,255], |
|
gold:[255,215,0], |
|
green:[0,128,0], |
|
indigo:[75,0,130], |
|
khaki:[240,230,140], |
|
lightblue:[173,216,230], |
|
lightcyan:[224,255,255], |
|
lightgreen:[144,238,144], |
|
lightgrey:[211,211,211], |
|
lightpink:[255,182,193], |
|
lightyellow:[255,255,224], |
|
lime:[0,255,0], |
|
magenta:[255,0,255], |
|
maroon:[128,0,0], |
|
navy:[0,0,128], |
|
olive:[128,128,0], |
|
orange:[255,165,0], |
|
pink:[255,192,203], |
|
purple:[128,0,128], |
|
violet:[128,0,128], |
|
red:[255,0,0], |
|
silver:[192,192,192], |
|
white:[255,255,255], |
|
yellow:[255,255,0], |
|
transparent: [255,255,255] |
|
}; |
|
|
|
|
|
|
|
/******************************************************************************/ |
|
/****************************** CLASS ANIMATIONS ******************************/ |
|
/******************************************************************************/ |
|
|
|
var classAnimationActions = ['add', 'remove', 'toggle'], |
|
shorthandStyles = { |
|
border: 1, |
|
borderBottom: 1, |
|
borderColor: 1, |
|
borderLeft: 1, |
|
borderRight: 1, |
|
borderTop: 1, |
|
borderWidth: 1, |
|
margin: 1, |
|
padding: 1 |
|
}; |
|
|
|
function getElementStyles() { |
|
var style = document.defaultView |
|
? document.defaultView.getComputedStyle(this, null) |
|
: this.currentStyle, |
|
newStyle = {}, |
|
key, |
|
camelCase; |
|
|
|
// webkit enumerates style porperties |
|
if (style && style.length && style[0] && style[style[0]]) { |
|
var len = style.length; |
|
while (len--) { |
|
key = style[len]; |
|
if (typeof style[key] == 'string') { |
|
camelCase = key.replace(/\-(\w)/g, function(all, letter){ |
|
return letter.toUpperCase(); |
|
}); |
|
newStyle[camelCase] = style[key]; |
|
} |
|
} |
|
} else { |
|
for (key in style) { |
|
if (typeof style[key] === 'string') { |
|
newStyle[key] = style[key]; |
|
} |
|
} |
|
} |
|
|
|
return newStyle; |
|
} |
|
|
|
function filterStyles(styles) { |
|
var name, value; |
|
for (name in styles) { |
|
value = styles[name]; |
|
if ( |
|
// ignore null and undefined values |
|
value == null || |
|
// ignore functions (when does this occur?) |
|
$.isFunction(value) || |
|
// shorthand styles that need to be expanded |
|
name in shorthandStyles || |
|
// ignore scrollbars (break in IE) |
|
(/scrollbar/).test(name) || |
|
|
|
// only colors or values that can be converted to numbers |
|
(!(/color/i).test(name) && isNaN(parseFloat(value))) |
|
) { |
|
delete styles[name]; |
|
} |
|
} |
|
|
|
return styles; |
|
} |
|
|
|
function styleDifference(oldStyle, newStyle) { |
|
var diff = { _: 0 }, // http://dev.jquery.com/ticket/5459 |
|
name; |
|
|
|
for (name in newStyle) { |
|
if (oldStyle[name] != newStyle[name]) { |
|
diff[name] = newStyle[name]; |
|
} |
|
} |
|
|
|
return diff; |
|
} |
|
|
|
$.effects.animateClass = function(value, duration, easing, callback) { |
|
if ($.isFunction(easing)) { |
|
callback = easing; |
|
easing = null; |
|
} |
|
|
|
return this.queue('fx', function() { |
|
var that = $(this), |
|
originalStyleAttr = that.attr('style') || ' ', |
|
originalStyle = filterStyles(getElementStyles.call(this)), |
|
newStyle, |
|
className = that.attr('className'); |
|
|
|
$.each(classAnimationActions, function(i, action) { |
|
if (value[action]) { |
|
that[action + 'Class'](value[action]); |
|
} |
|
}); |
|
newStyle = filterStyles(getElementStyles.call(this)); |
|
that.attr('className', className); |
|
|
|
that.animate(styleDifference(originalStyle, newStyle), duration, easing, function() { |
|
$.each(classAnimationActions, function(i, action) { |
|
if (value[action]) { that[action + 'Class'](value[action]); } |
|
}); |
|
// work around bug in IE by clearing the cssText before setting it |
|
if (typeof that.attr('style') == 'object') { |
|
that.attr('style').cssText = ''; |
|
that.attr('style').cssText = originalStyleAttr; |
|
} else { |
|
that.attr('style', originalStyleAttr); |
|
} |
|
if (callback) { callback.apply(this, arguments); } |
|
}); |
|
|
|
// $.animate adds a function to the end of the queue |
|
// but we want it at the front |
|
var queue = $.queue(this), |
|
anim = queue.splice(queue.length - 1, 1)[0]; |
|
queue.splice(1, 0, anim); |
|
$.dequeue(this); |
|
}); |
|
}; |
|
|
|
$.fn.extend({ |
|
_addClass: $.fn.addClass, |
|
addClass: function(classNames, speed, easing, callback) { |
|
return speed ? $.effects.animateClass.apply(this, [{ add: classNames },speed,easing,callback]) : this._addClass(classNames); |
|
}, |
|
|
|
_removeClass: $.fn.removeClass, |
|
removeClass: function(classNames,speed,easing,callback) { |
|
return speed ? $.effects.animateClass.apply(this, [{ remove: classNames },speed,easing,callback]) : this._removeClass(classNames); |
|
}, |
|
|
|
_toggleClass: $.fn.toggleClass, |
|
toggleClass: function(classNames, force, speed, easing, callback) { |
|
if ( typeof force == "boolean" || force === undefined ) { |
|
if ( !speed ) { |
|
// without speed parameter; |
|
return this._toggleClass(classNames, force); |
|
} else { |
|
return $.effects.animateClass.apply(this, [(force?{add:classNames}:{remove:classNames}),speed,easing,callback]); |
|
} |
|
} else { |
|
// without switch parameter; |
|
return $.effects.animateClass.apply(this, [{ toggle: classNames },force,speed,easing]); |
|
} |
|
}, |
|
|
|
switchClass: function(remove,add,speed,easing,callback) { |
|
return $.effects.animateClass.apply(this, [{ add: add, remove: remove },speed,easing,callback]); |
|
} |
|
}); |
|
|
|
|
|
|
|
/******************************************************************************/ |
|
/*********************************** EFFECTS **********************************/ |
|
/******************************************************************************/ |
|
|
|
$.extend($.effects, { |
|
version: "@VERSION", |
|
|
|
// Saves a set of properties in a data storage |
|
save: function(element, set) { |
|
for(var i=0; i < set.length; i++) { |
|
if(set[i] !== null) element.data("ec.storage."+set[i], element[0].style[set[i]]); |
|
} |
|
}, |
|
|
|
// Restores a set of previously saved properties from a data storage |
|
restore: function(element, set) { |
|
for(var i=0; i < set.length; i++) { |
|
if(set[i] !== null) element.css(set[i], element.data("ec.storage."+set[i])); |
|
} |
|
}, |
|
|
|
setMode: function(el, mode) { |
|
if (mode == 'toggle') mode = el.is(':hidden') ? 'show' : 'hide'; // Set for toggle |
|
return mode; |
|
}, |
|
|
|
getBaseline: function(origin, original) { // Translates a [top,left] array into a baseline value |
|
// this should be a little more flexible in the future to handle a string & hash |
|
var y, x; |
|
switch (origin[0]) { |
|
case 'top': y = 0; break; |
|
case 'middle': y = 0.5; break; |
|
case 'bottom': y = 1; break; |
|
default: y = origin[0] / original.height; |
|
}; |
|
switch (origin[1]) { |
|
case 'left': x = 0; break; |
|
case 'center': x = 0.5; break; |
|
case 'right': x = 1; break; |
|
default: x = origin[1] / original.width; |
|
}; |
|
return {x: x, y: y}; |
|
}, |
|
|
|
// 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 = $('<div></div>') |
|
.addClass('ui-effects-wrapper') |
|
.css({ |
|
fontSize: '100%', |
|
background: 'transparent', |
|
border: 'none', |
|
margin: 0, |
|
padding: 0 |
|
}); |
|
|
|
element.wrap(wrapper); |
|
wrapper = element.parent(); //Hotfix for jQuery 1.4 since some change in wrap() seems to actually loose the reference to the wrapped element |
|
|
|
// transfer positioning properties to the wrapper |
|
if (element.css('position') == 'static') { |
|
wrapper.css({ position: 'relative' }); |
|
element.css({ position: 'relative' }); |
|
} else { |
|
$.extend(props, { |
|
position: element.css('position'), |
|
zIndex: element.css('z-index') |
|
}); |
|
$.each(['top', 'left', 'bottom', 'right'], function(i, pos) { |
|
props[pos] = element.css(pos); |
|