Created
January 29, 2014 01:45
-
-
Save jdivock/8680209 to your computer and use it in GitHub Desktop.
just the jquery animate code ported from 1.8 . . . hacked up to be used on a project where we're forced to use 1.7.2
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var elemdisplay = { | |
BODY: "block" | |
}, curCSS, iframe, iframeDoc, cssExpand = ["Top", "Right", "Bottom", "Left"], | |
core_pnum = /[\-+]?(?:\d*\.|)\d+(?:[eE][\-+]?\d+|)/.source, | |
cssPrefixes = ["Webkit", "O", "Moz", "ms"], | |
rnumsplit = new RegExp("^(" + core_pnum + ")(.*)$", "i"), | |
rnumnonpx = new RegExp("^(" + core_pnum + ")(?!px)[a-z%]+$", "i"), | |
ralpha = /alpha\([^)]*\)/i, | |
ropacity = /opacity=([^)]*)/, | |
rposition = /^(top|right|bottom|left)$/, | |
// swappable if display is none or starts with table except "table", "table-cell", or "table-caption" | |
// see here for display values: https://developer.mozilla.org/en-US/docs/CSS/display | |
rdisplayswap = /^(none|table(?!-c[ea]).+)/, | |
rmargin = /^margin/, | |
cssNormalTransform = { | |
letterSpacing: 0, | |
fontWeight: 400 | |
}, | |
rrelNum = new RegExp("^([-+])=(" + core_pnum + ")", "i"); | |
if (window.getComputedStyle) { | |
curCSS = function(elem, name) { | |
var ret, width, minWidth, maxWidth, | |
computed = window.getComputedStyle(elem, null), | |
style = elem.style; | |
if (computed) { | |
// getPropertyValue is only needed for .css('filter') in IE9, see #12537 | |
ret = computed.getPropertyValue(name) || computed[name]; | |
if (ret === "" && !jQuery.contains(elem.ownerDocument, elem)) { | |
ret = jQuery.style(elem, name); | |
} | |
// A tribute to the "awesome hack by Dean Edwards" | |
// Chrome < 17 and Safari 5.0 uses "computed value" instead of "used value" for margin-right | |
// Safari 5.1.7 (at least) returns percentage for a larger set of values, but width seems to be reliably pixels | |
// this is against the CSSOM draft spec: http://dev.w3.org/csswg/cssom/#resolved-values | |
if (rnumnonpx.test(ret) && rmargin.test(name)) { | |
width = style.width; | |
minWidth = style.minWidth; | |
maxWidth = style.maxWidth; | |
style.minWidth = style.maxWidth = style.width = ret; | |
ret = computed.width; | |
style.width = width; | |
style.minWidth = minWidth; | |
style.maxWidth = maxWidth; | |
} | |
} | |
return ret; | |
}; | |
} else if (document.documentElement.currentStyle) { | |
curCSS = function(elem, name) { | |
var left, rsLeft, | |
ret = elem.currentStyle && elem.currentStyle[name], | |
style = elem.style; | |
// Avoid setting ret to empty string here | |
// so we don't default to auto | |
if (ret == null && style && style[name]) { | |
ret = style[name]; | |
} | |
// From the awesome hack by Dean Edwards | |
// http://erik.eae.net/archives/2007/07/27/18.54.15/#comment-102291 | |
// If we're not dealing with a regular pixel number | |
// but a number that has a weird ending, we need to convert it to pixels | |
// but not position css attributes, as those are proportional to the parent element instead | |
// and we can't measure the parent instead because it might trigger a "stacking dolls" problem | |
if (rnumnonpx.test(ret) && !rposition.test(name)) { | |
// Remember the original values | |
left = style.left; | |
rsLeft = elem.runtimeStyle && elem.runtimeStyle.left; | |
// Put in the new values to get a computed value out | |
if (rsLeft) { | |
elem.runtimeStyle.left = elem.currentStyle.left; | |
} | |
style.left = name === "fontSize" ? "1em" : ret; | |
ret = style.pixelLeft + "px"; | |
// Revert the changed values | |
style.left = left; | |
if (rsLeft) { | |
elem.runtimeStyle.left = rsLeft; | |
} | |
} | |
return ret === "" ? "auto" : ret; | |
}; | |
} | |
jQuery.extend({ | |
// Add in style property hooks for overriding the default | |
// behavior of getting and setting a style property | |
cssHooks: { | |
opacity: { | |
get: function(elem, computed) { | |
if (computed) { | |
// We should always get a number back from opacity | |
var ret = curCSS(elem, "opacity"); | |
return ret === "" ? "1" : ret; | |
} | |
} | |
} | |
}, | |
// Exclude the following css properties to add px | |
cssNumber: { | |
"fillOpacity": true, | |
"fontWeight": true, | |
"lineHeight": true, | |
"opacity": true, | |
"orphans": true, | |
"widows": true, | |
"zIndex": true, | |
"zoom": true | |
}, | |
// Add in properties whose names you wish to fix before | |
// setting or getting the value | |
cssProps: { | |
// normalize float css property | |
"float": jQuery.support.cssFloat ? "cssFloat" : "styleFloat" | |
}, | |
// Get and set the style property on a DOM Node | |
style: function(elem, name, value, extra) { | |
// Don't set styles on text and comment nodes | |
if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { | |
return; | |
} | |
// Make sure that we're working with the right name | |
var ret, type, hooks, | |
origName = jQuery.camelCase(name), | |
style = elem.style; | |
name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(style, origName)); | |
// gets hook for the prefixed version | |
// followed by the unprefixed version | |
hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; | |
// Check if we're setting a value | |
if (value !== undefined) { | |
type = typeof value; | |
// convert relative number strings (+= or -=) to relative numbers. #7345 | |
if (type === "string" && (ret = rrelNum.exec(value))) { | |
value = (ret[1] + 1) * ret[2] + parseFloat(jQuery.css(elem, name)); | |
// Fixes bug #9237 | |
type = "number"; | |
} | |
// Make sure that NaN and null values aren't set. See: #7116 | |
if (value == null || type === "number" && isNaN(value)) { | |
return; | |
} | |
// If a number was passed in, add 'px' to the (except for certain CSS properties) | |
if (type === "number" && !jQuery.cssNumber[origName]) { | |
value += "px"; | |
} | |
// If a hook was provided, use that value, otherwise just set the specified value | |
if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) { | |
// Wrapped to prevent IE from throwing errors when 'invalid' values are provided | |
// Fixes bug #5509 | |
try { | |
style[name] = value; | |
} catch (e) {} | |
} | |
} else { | |
// If a hook was provided get the non-computed value from there | |
if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) { | |
return ret; | |
} | |
// Otherwise just get the value from the style object | |
return style[name]; | |
} | |
}, | |
css: function(elem, name, numeric, extra) { | |
var val, num, hooks, | |
origName = jQuery.camelCase(name); | |
// Make sure that we're working with the right name | |
name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(elem.style, origName)); | |
// gets hook for the prefixed version | |
// followed by the unprefixed version | |
hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; | |
// If a hook was provided get the computed value from there | |
if (hooks && "get" in hooks) { | |
val = hooks.get(elem, true, extra); | |
} | |
// Otherwise, if a way to get the computed value exists, use that | |
if (val === undefined) { | |
val = curCSS(elem, name); | |
} | |
//convert "normal" to computed value | |
if (val === "normal" && name in cssNormalTransform) { | |
val = cssNormalTransform[name]; | |
} | |
// Return, converting to number if forced or a qualifier was provided and val looks numeric | |
if (numeric || extra !== undefined) { | |
num = parseFloat(val); | |
return numeric || jQuery.isNumeric(num) ? num || 0 : val; | |
} | |
return val; | |
}, | |
// A method for quickly swapping in/out CSS properties to get correct calculations | |
swap: function(elem, options, callback) { | |
var ret, name, | |
old = {}; | |
// Remember the old values, and insert the new ones | |
for (name in options) { | |
old[name] = elem.style[name]; | |
elem.style[name] = options[name]; | |
} | |
ret = callback.call(elem); | |
// Revert the old values | |
for (name in options) { | |
elem.style[name] = old[name]; | |
} | |
return ret; | |
} | |
}); | |
jQuery.fn.extend({ | |
style: function(elem, name, value, extra) { | |
// Don't set styles on text and comment nodes | |
if (!elem || elem.nodeType === 3 || elem.nodeType === 8 || !elem.style) { | |
return; | |
} | |
// Make sure that we're working with the right name | |
var ret, type, hooks, | |
origName = jQuery.camelCase(name), | |
style = elem.style; | |
name = jQuery.cssProps[origName] || (jQuery.cssProps[origName] = vendorPropName(style, origName)); | |
// gets hook for the prefixed version | |
// followed by the unprefixed version | |
hooks = jQuery.cssHooks[name] || jQuery.cssHooks[origName]; | |
// Check if we're setting a value | |
if (value !== undefined) { | |
type = typeof value; | |
// convert relative number strings (+= or -=) to relative numbers. #7345 | |
if (type === "string" && (ret = rrelNum.exec(value))) { | |
value = (ret[1] + 1) * ret[2] + parseFloat(jQuery.css(elem, name)); | |
// Fixes bug #9237 | |
type = "number"; | |
} | |
// Make sure that NaN and null values aren't set. See: #7116 | |
if (value == null || type === "number" && isNaN(value)) { | |
return; | |
} | |
// If a number was passed in, add 'px' to the (except for certain CSS properties) | |
if (type === "number" && !jQuery.cssNumber[origName]) { | |
value += "px"; | |
} | |
// If a hook was provided, use that value, otherwise just set the specified value | |
if (!hooks || !("set" in hooks) || (value = hooks.set(elem, value, extra)) !== undefined) { | |
// Wrapped to prevent IE from throwing errors when 'invalid' values are provided | |
// Fixes bug #5509 | |
try { | |
style[name] = value; | |
} catch (e) {} | |
} | |
} else { | |
// If a hook was provided get the non-computed value from there | |
if (hooks && "get" in hooks && (ret = hooks.get(elem, false, extra)) !== undefined) { | |
return ret; | |
} | |
// Otherwise just get the value from the style object | |
return style[name]; | |
} | |
}, | |
css: function(name, value) { | |
return jQuery.access(this, function(elem, name, value) { | |
return value !== undefined ? | |
jQuery.style(elem, name, value) : | |
jQuery.css(elem, name); | |
}, name, value, arguments.length > 1); | |
} | |
}); | |
function isHidden(elem, el) { | |
elem = el || elem; | |
return jQuery.css(elem, "display") === "none" || !jQuery.contains(elem.ownerDocument, elem); | |
} | |
function css_defaultDisplay(nodeName) { | |
if (elemdisplay[nodeName]) { | |
return elemdisplay[nodeName]; | |
} | |
var elem = jQuery("<" + nodeName + ">").appendTo(document.body), | |
display = elem.css("display"); | |
elem.remove(); | |
// If the simple way fails, | |
// get element's real default display by attaching it to a temp iframe | |
if (display === "none" || display === "") { | |
// Use the already-created iframe if possible | |
iframe = document.body.appendChild( | |
iframe || jQuery.extend(document.createElement("iframe"), { | |
frameBorder: 0, | |
width: 0, | |
height: 0 | |
}) | |
); | |
// Create a cacheable copy of the iframe document on first call. | |
// IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML | |
// document to it; WebKit & Firefox won't allow reusing the iframe document. | |
if (!iframeDoc || !iframe.createElement) { | |
iframeDoc = (iframe.contentWindow || iframe.contentDocument).document; | |
iframeDoc.write("<!doctype html><html><body>"); | |
iframeDoc.close(); | |
} | |
elem = iframeDoc.body.appendChild(iframeDoc.createElement(nodeName)); | |
display = curCSS(elem, "display"); | |
document.body.removeChild(iframe); | |
} | |
// Store the correct default display | |
elemdisplay[nodeName] = display; | |
return display; | |
} | |
function defaultPrefilter(elem, props, opts) { | |
var index, prop, value, length, dataShow, toggle, tween, hooks, oldfire, | |
anim = this, | |
style = elem.style, | |
orig = {}, | |
handled = [], | |
hidden = elem.nodeType && isHidden(elem); | |
// handle queue: false promises | |
if (!opts.queue) { | |
hooks = jQuery._queueHooks(elem, "fx"); | |
if (hooks.unqueued == null) { | |
hooks.unqueued = 0; | |
oldfire = hooks.empty.fire; | |
hooks.empty.fire = function() { | |
if (!hooks.unqueued) { | |
oldfire(); | |
} | |
}; | |
} | |
hooks.unqueued++; | |
anim.always(function() { | |
// doing this makes sure that the complete handler will be called | |
// before this completes | |
anim.always(function() { | |
hooks.unqueued--; | |
if (!jQuery.queue(elem, "fx").length) { | |
hooks.empty.fire(); | |
} | |
}); | |
}); | |
} | |
// height/width overflow pass | |
if (elem.nodeType === 1 && ("height" in props || "width" in props)) { | |
// Make sure that nothing sneaks out | |
// Record all 3 overflow attributes because IE does not | |
// change the overflow attribute when overflowX and | |
// overflowY are set to the same value | |
opts.overflow = [style.overflow, style.overflowX, style.overflowY]; | |
// Set display property to inline-block for height/width | |
// animations on inline elements that are having width/height animated | |
if (jQuery.css(elem, "display") === "inline" && | |
jQuery.css(elem, "float") === "none") { | |
// inline-level elements accept inline-block; | |
// block-level elements need to be inline with layout | |
if (!jQuery.support.inlineBlockNeedsLayout || css_defaultDisplay(elem.nodeName) === "inline") { | |
style.display = "inline-block"; | |
} else { | |
style.zoom = 1; | |
} | |
} | |
} | |
if (opts.overflow) { | |
style.overflow = "hidden"; | |
if (!jQuery.support.shrinkWrapBlocks) { | |
anim.done(function() { | |
style.overflow = opts.overflow[0]; | |
style.overflowX = opts.overflow[1]; | |
style.overflowY = opts.overflow[2]; | |
}); | |
} | |
} | |
// show/hide pass | |
for (index in props) { | |
value = props[index]; | |
if (rfxtypes.exec(value)) { | |
delete props[index]; | |
toggle = toggle || value === "toggle"; | |
if (value === (hidden ? "hide" : "show")) { | |
continue; | |
} | |
handled.push(index); | |
} | |
} | |
length = handled.length; | |
if (length) { | |
dataShow = jQuery._data(elem, "fxshow") || jQuery._data(elem, "fxshow", {}); | |
if ("hidden" in dataShow) { | |
hidden = dataShow.hidden; | |
} | |
// store state if its toggle - enables .stop().toggle() to "reverse" | |
if (toggle) { | |
dataShow.hidden = !hidden; | |
} | |
if (hidden) { | |
jQuery(elem).show(); | |
} else { | |
anim.done(function() { | |
jQuery(elem).hide(); | |
}); | |
} | |
anim.done(function() { | |
var prop; | |
jQuery.removeData(elem, "fxshow", true); | |
for (prop in orig) { | |
jQuery.style(elem, prop, orig[prop]); | |
} | |
}); | |
for (index = 0; index < length; index++) { | |
prop = handled[index]; | |
tween = anim.createTween(prop, hidden ? dataShow[prop] : 0); | |
orig[prop] = dataShow[prop] || jQuery.style(elem, prop); | |
if (!(prop in dataShow)) { | |
console.log('prop', prop); | |
dataShow[prop] = tween.start; | |
if (hidden) { | |
tween.end = tween.start; | |
tween.start = prop === "width" || prop === "height" ? 1 : 0; | |
} | |
} | |
} | |
} | |
} | |
var fxNow, timerId, | |
rfxtypes = /^(?:toggle|show|hide)$/, | |
rfxnum = new RegExp("^(?:([-+])=|)(" + core_pnum + ")([a-z%]*)$", "i"), | |
rrun = /queueHooks$/, | |
animationPrefilters = [defaultPrefilter], | |
tweeners = { | |
"*": [ | |
function(prop, value) { | |
// debugger; | |
var end, unit, | |
tween = this.createTween(prop, value), | |
parts = rfxnum.exec(value), | |
target = tween.cur(), | |
start = +target || 0, | |
scale = 1, | |
maxIterations = 20; | |
// if (target) { | |
// target = target.substring(0, target.length - 1); | |
// start = +target || 0; | |
// } | |
if (parts) { | |
end = +parts[2]; | |
unit = parts[3] || (jQuery.cssNumber[prop] ? "" : "px"); | |
// We need to compute starting value | |
if (unit !== "px" && start) { | |
// Iteratively approximate from a nonzero starting point | |
// Prefer the current property, because this process will be trivial if it uses the same units | |
// Fallback to end or a simple constant | |
start = jQuery.css(tween.elem, prop, true) || end || 1; | |
console.log('here', start); | |
do { | |
// If previous iteration zeroed out, double until we get *something* | |
// Use a string for doubling factor so we don't accidentally see scale as unchanged below | |
scale = scale || ".5"; | |
// Adjust and apply | |
start = start / scale; | |
jQuery.style(tween.elem, prop, start + unit); | |
// Update scale, tolerating zero or NaN from tween.cur() | |
// And breaking the loop if scale is unchanged or perfect, or if we've just had enough | |
} while (scale !== (scale = tween.cur() / target) && scale !== 1 && --maxIterations); | |
} | |
tween.unit = unit; | |
tween.start = start; | |
// If a +=/-= token was provided, we're doing a relative animation | |
tween.end = parts[1] ? start + (parts[1] + 1) * end : end; | |
} | |
return tween; | |
} | |
] | |
}; | |
function createFxNow() { | |
setTimeout(function() { | |
fxNow = undefined; | |
}, 0); | |
return (fxNow = jQuery.now()); | |
} | |
function propFilter(props, specialEasing) { | |
var index, name, easing, value, hooks; | |
// camelCase, specialEasing and expand cssHook pass | |
for (index in props) { | |
name = jQuery.camelCase(index); | |
easing = specialEasing[name]; | |
value = props[index]; | |
if (jQuery.isArray(value)) { | |
easing = value[1]; | |
value = props[index] = value[0]; | |
} | |
if (index !== name) { | |
props[name] = value; | |
delete props[index]; | |
} | |
hooks = jQuery.cssHooks[name]; | |
if (hooks && "expand" in hooks) { | |
value = hooks.expand(value); | |
delete props[name]; | |
// not quite $.extend, this wont overwrite keys already present. | |
// also - reusing 'index' from above because we have the correct "name" | |
for (index in value) { | |
if (!(index in props)) { | |
props[index] = value[index]; | |
specialEasing[index] = easing; | |
} | |
} | |
} else { | |
specialEasing[name] = easing; | |
} | |
} | |
} | |
function createTweens(animation, props) { | |
jQuery.each(props, function(prop, value) { | |
var collection = (tweeners[prop] || []).concat(tweeners["*"]), | |
index = 0, | |
length = collection.length; | |
for (; index < length; index++) { | |
if (collection[index].call(animation, prop, value)) { | |
// we're done with this property | |
return; | |
} | |
} | |
}); | |
} | |
function Animation(elem, properties, options) { | |
var result, | |
index = 0, | |
tweenerIndex = 0, | |
length = animationPrefilters.length, | |
deferred = jQuery.Deferred().always(function() { | |
// don't match elem in the :animated selector | |
delete tick.elem; | |
}), | |
tick = function() { | |
var currentTime = fxNow || createFxNow(), | |
remaining = Math.max(0, animation.startTime + animation.duration - currentTime), | |
// archaic crash bug won't allow us to use 1 - ( 0.5 || 0 ) (#12497) | |
temp = remaining / animation.duration || 0, | |
percent = 1 - temp, | |
index = 0, | |
length = animation.tweens.length; | |
for (; index < length; index++) { | |
animation.tweens[index].run(percent); | |
} | |
deferred.notifyWith(elem, [animation, percent, remaining]); | |
if (percent < 1 && length) { | |
return remaining; | |
} else { | |
deferred.resolveWith(elem, [animation]); | |
return false; | |
} | |
}, | |
animation = deferred.promise({ | |
elem: elem, | |
props: jQuery.extend({}, properties), | |
opts: jQuery.extend(true, { | |
specialEasing: {} | |
}, options), | |
originalProperties: properties, | |
originalOptions: options, | |
startTime: fxNow || createFxNow(), | |
duration: options.duration, | |
tweens: [], | |
createTween: function(prop, end, easing) { | |
var tween = jQuery.Tween(elem, animation.opts, prop, end, | |
animation.opts.specialEasing[prop] || animation.opts.easing); | |
animation.tweens.push(tween); | |
return tween; | |
}, | |
stop: function(gotoEnd) { | |
var index = 0, | |
// if we are going to the end, we want to run all the tweens | |
// otherwise we skip this part | |
length = gotoEnd ? animation.tweens.length : 0; | |
for (; index < length; index++) { | |
animation.tweens[index].run(1); | |
} | |
// resolve when we played the last frame | |
// otherwise, reject | |
if (gotoEnd) { | |
deferred.resolveWith(elem, [animation, gotoEnd]); | |
} else { | |
deferred.rejectWith(elem, [animation, gotoEnd]); | |
} | |
return this; | |
} | |
}), | |
props = animation.props; | |
propFilter(props, animation.opts.specialEasing); | |
for (; index < length; index++) { | |
result = animationPrefilters[index].call(animation, elem, props, animation.opts); | |
if (result) { | |
return result; | |
} | |
} | |
createTweens(animation, props); | |
if (jQuery.isFunction(animation.opts.start)) { | |
animation.opts.start.call(elem, animation); | |
} | |
jQuery.fx.timer( | |
jQuery.extend(tick, { | |
anim: animation, | |
queue: animation.opts.queue, | |
elem: elem | |
}) | |
); | |
// attach callbacks from options | |
return animation.progress(animation.opts.progress) | |
.done(animation.opts.done, animation.opts.complete) | |
.fail(animation.opts.fail) | |
.always(animation.opts.always); | |
} | |
function Tween(elem, options, prop, end, easing) { | |
return new Tween.prototype.init(elem, options, prop, end, easing); | |
} | |
jQuery.Tween = Tween; | |
var START; | |
Tween.prototype = { | |
constructor: Tween, | |
init: function(elem, options, prop, end, easing, unit) { | |
// debugger; | |
this.elem = elem; | |
this.prop = prop; | |
this.easing = easing || "swing"; | |
this.options = options; | |
this.start = this.now = this.cur(); | |
this.end = end; | |
this.unit = unit || (jQuery.cssNumber[prop] ? "" : "px"); | |
// START = this.start; | |
this.first = true; | |
}, | |
cur: function() { | |
var hooks = Tween.propHooks[this.prop]; | |
return hooks && hooks.get ? | |
hooks.get(this) : | |
Tween.propHooks._default.get(this); | |
}, | |
run: function(percent) { | |
// var start = START.toString().substring(0, START.length - 1); | |
// this.start = START.toString().substring(0, START.length - 1); | |
// console.log('start', START.toString().substring(0, START.length - 1)); | |
console.log('start', this.start, this.end); | |
var eased, | |
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 | |
); | |
} else { | |
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) { | |
hooks.set(this); | |
} else { | |
Tween.propHooks._default.set(this); | |
} | |
return this; | |
} | |
}; | |
Tween.prototype.init.prototype = Tween.prototype; | |
Tween.propHooks = { | |
_default: { | |
get: function(tween) { | |
var result; | |
if (tween.elem[tween.prop] != null && | |
(!tween.elem.style || tween.elem.style[tween.prop] == null)) { | |
return tween.elem[tween.prop]; | |
} | |
// passing any value as a 4th parameter to .css will automatically | |
// attempt a parseFloat and fallback to a string if the parse fails | |
// so, 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, false, ""); | |
// Empty strings, null, undefined and "auto" are converted to 0. | |
return !result || result === "auto" ? 0 : result; | |
}, | |
set: function(tween) { | |
// use step hook for back compat - use cssHook if its there - use .style if its | |
// available and use plain properties where available | |
if (jQuery.fx.step[tween.prop]) { | |
jQuery.fx.step[tween.prop](tween); | |
} else if (tween.elem.style && (tween.elem.style[jQuery.cssProps[tween.prop]] != null || jQuery.cssHooks[tween.prop])) { | |
jQuery.style(tween.elem, tween.prop, tween.now + tween.unit); | |
} else { | |
tween.elem[tween.prop] = tween.now; | |
} | |
} | |
} | |
}; | |
function genFx(type, includeWidth) { | |
var which, | |
attrs = { | |
height: type | |
}, | |
i = 0; | |
// if we include width, step value is 1 to do all cssExpand values, | |
// if we don't include width, step value is 2 to skip over Left and Right | |
includeWidth = includeWidth ? 1 : 0; | |
for (; i < 4; i += 2 - includeWidth) { | |
which = cssExpand[i]; | |
attrs["margin" + which] = attrs["padding" + which] = type; | |
} | |
if (includeWidth) { | |
attrs.opacity = attrs.width = type; | |
} | |
return attrs; | |
} | |
// Remove in 2.0 - this supports IE8's panic based approach | |
// to setting things on disconnected nodes | |
Tween.propHooks.scrollTop = Tween.propHooks.scrollLeft = { | |
set: function(tween) { | |
if (tween.elem.nodeType && tween.elem.parentNode) { | |
tween.elem[tween.prop] = tween.now; | |
} | |
} | |
}; | |
jQuery.each(["toggle", "show", "hide"], function(i, name) { | |
var cssFn = jQuery.fn[name]; | |
jQuery.fn[name] = function(speed, easing, callback) { | |
return speed == null || typeof speed === "boolean" || | |
// special check for .toggle( handler, handler, ... ) | |
(!i && jQuery.isFunction(speed) && jQuery.isFunction(easing)) ? | |
cssFn.apply(this, arguments) : | |
this.animate(genFx(name, true), speed, easing, callback); | |
}; | |
}); | |
var DIR; | |
jQuery.fn.extend({ | |
fadeTo: function(speed, to, easing, callback) { | |
// show any hidden elements after setting opacity to 0 | |
return this.filter(isHidden).css("opacity", 0).show() | |
// animate to the value specified | |
.end().animate({ | |
opacity: to | |
}, speed, easing, callback); | |
}, | |
animate2: function(prop, speed, easing, callback) { | |
var empty = jQuery.isEmptyObject(prop), | |
optall = jQuery.speed(speed, easing, callback), | |
doAnimation = function() { | |
// Operate on a copy of prop so per-property easing won't be lost | |
var anim = Animation(this, jQuery.extend({}, prop), optall); | |
// Empty animations resolve immediately | |
if (empty) { | |
anim.stop(true); | |
} | |
}; | |
return empty || optall.queue === false ? | |
this.each(doAnimation) : | |
this.queue(optall.queue, doAnimation); | |
}, | |
stop: function(type, clearQueue, gotoEnd) { | |
var stopQueue = function(hooks) { | |
var stop = hooks.stop; | |
delete hooks.stop; | |
stop(gotoEnd); | |
}; | |
if (typeof type !== "string") { | |
gotoEnd = clearQueue; | |
clearQueue = type; | |
type = undefined; | |
} | |
if (clearQueue && type !== false) { | |
this.queue(type || "fx", []); | |
} | |
return this.each(function() { | |
var dequeue = true, | |
index = type != null && type + "queueHooks", | |
timers = jQuery.timers, | |
data = jQuery._data(this); | |
if (index) { | |
if (data[index] && data[index].stop) { | |
stopQueue(data[index]); | |
} | |
} else { | |
for (index in data) { | |
if (data[index] && data[index].stop && rrun.test(index)) { | |
stopQueue(data[index]); | |
} | |
} | |
} | |
for (index = timers.length; index--;) { | |
if (timers[index].elem === this && (type == null || timers[index].queue === type)) { | |
timers[index].anim.stop(gotoEnd); | |
dequeue = false; | |
timers.splice(index, 1); | |
} | |
} | |
// start the next in the queue if the last step wasn't forced | |
// timers currently will call their complete callbacks, which will dequeue | |
// but only if they were gotoEnd | |
if (dequeue || !gotoEnd) { | |
jQuery.dequeue(this, type); | |
} | |
}); | |
} | |
}); | |
// Generate parameters to create a standard animation | |
// Generate shortcuts for custom animations | |
jQuery.each({ | |
slideDown: genFx("show"), | |
slideUp: genFx("hide"), | |
slideToggle: genFx("toggle"), | |
fadeIn: { | |
opacity: "show" | |
}, | |
fadeOut: { | |
opacity: "hide" | |
}, | |
fadeToggle: { | |
opacity: "toggle" | |
} | |
}, function(name, props) { | |
jQuery.fn[name] = function(speed, easing, callback) { | |
return this.animate(props, speed, easing, callback); | |
}; | |
}); | |
jQuery.speed = function(speed, easing, fn) { | |
var opt = speed && typeof speed === "object" ? jQuery.extend({}, speed) : { | |
complete: fn || !fn && easing || jQuery.isFunction(speed) && speed, | |
duration: speed, | |
easing: fn && easing || easing && !jQuery.isFunction(easing) && easing | |
}; | |
opt.duration = jQuery.fx.off ? 0 : typeof opt.duration === "number" ? opt.duration : | |
opt.duration in jQuery.fx.speeds ? jQuery.fx.speeds[opt.duration] : jQuery.fx.speeds._default; | |
// normalize opt.queue - true/undefined/null -> "fx" | |
if (opt.queue == null || opt.queue === true) { | |
opt.queue = "fx"; | |
} | |
// Queueing | |
opt.old = opt.complete; | |
opt.complete = function() { | |
if (jQuery.isFunction(opt.old)) { | |
opt.old.call(this); | |
} | |
if (opt.queue) { | |
jQuery.dequeue(this, opt.queue); | |
} | |
}; | |
return opt; | |
}; | |
jQuery.easing = { | |
linear: function(p) { | |
return p; | |
}, | |
swing: function(p) { | |
return 0.5 - Math.cos(p * Math.PI) / 2; | |
} | |
}; | |
jQuery.timers = []; | |
jQuery.fx = Tween.prototype.init; | |
jQuery.fx.tick = function() { | |
var timer, | |
timers = jQuery.timers, | |
i = 0; | |
fxNow = jQuery.now(); | |
for (; i < timers.length; i++) { | |
timer = timers[i]; | |
// Checks the timer has not already been removed | |
if (!timer() && timers[i] === timer) { | |
timers.splice(i--, 1); | |
} | |
} | |
if (!timers.length) { | |
jQuery.fx.stop(); | |
} | |
fxNow = undefined; | |
}; | |
jQuery.fx.timer = function(timer) { | |
if (timer() && jQuery.timers.push(timer) && !timerId) { | |
timerId = setInterval(jQuery.fx.tick, jQuery.fx.interval); | |
} | |
}; | |
jQuery.fx.interval = 13; | |
jQuery.fx.stop = function() { | |
clearInterval(timerId); | |
timerId = null; | |
}; | |
jQuery.fx.speeds = { | |
slow: 600, | |
fast: 200, | |
// Default speed | |
_default: 400 | |
}; | |
// Back Compat <1.8 extension point | |
jQuery.fx.step = {}; | |
if (jQuery.expr && jQuery.expr.filters) { | |
jQuery.expr.filters.animated = function(elem) { | |
return jQuery.grep(jQuery.timers, function(fn) { | |
return elem === fn.elem; | |
}).length; | |
}; | |
} | |
var rroot = /^(?:body|html)$/i; | |
jQuery.fn.extend({ | |
access: function(elems, fn, key, value, chainable, emptyGet, pass) { | |
var exec, | |
bulk = key == null, | |
i = 0, | |
length = elems.length; | |
// Sets many values | |
if (key && typeof key === "object") { | |
for (i in key) { | |
jQuery.access(elems, fn, i, key[i], 1, emptyGet, value); | |
} | |
chainable = 1; | |
// Sets one value | |
} else if (value !== undefined) { | |
// Optionally, function values get executed if exec is true | |
exec = pass === undefined && jQuery.isFunction(value); | |
if (bulk) { | |
// Bulk operations only iterate when executing function values | |
if (exec) { | |
exec = fn; | |
fn = function(elem, key, value) { | |
return exec.call(jQuery(elem), value); | |
}; | |
// Otherwise they run against the entire set | |
} else { | |
fn.call(elems, value); | |
fn = null; | |
} | |
} | |
if (fn) { | |
for (; i < length; i++) { | |
fn(elems[i], key, exec ? value.call(elems[i], i, fn(elems[i], key)) : value, pass); | |
} | |
} | |
chainable = 1; | |
} | |
return chainable ? | |
elems : | |
// Gets | |
bulk ? | |
fn.call(elems) : | |
length ? fn(elems[0], key) : emptyGet; | |
} | |
}); | |
function vendorPropName(style, name) { | |
// shortcut for names that are not vendor prefixed | |
if (name in style) { | |
return name; | |
} | |
// check for vendor prefixed names | |
var capName = name.charAt(0).toUpperCase() + name.slice(1), | |
origName = name, | |
i = cssPrefixes.length; | |
while (i--) { | |
name = cssPrefixes[i] + capName; | |
if (name in style) { | |
return name; | |
} | |
} | |
return origName; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment