Merge branch 'master' of github.com:jquery/jquery
This commit is contained in:
commit
c470db6950
27
src/core.js
27
src/core.js
|
@ -565,24 +565,17 @@ jQuery.extend({
|
|||
|
||||
noop: function() {},
|
||||
|
||||
// Evalulates a script in a global context
|
||||
// Evaluates a script in a global context
|
||||
// Workarounds based on findings by Jim Driscoll
|
||||
// http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context
|
||||
globalEval: function( data ) {
|
||||
if ( data && rnotwhite.test(data) ) {
|
||||
// Inspired by code by Andrea Giammarchi
|
||||
// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
|
||||
var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement,
|
||||
script = document.createElement( "script" );
|
||||
|
||||
if ( jQuery.support.scriptEval() ) {
|
||||
script.appendChild( document.createTextNode( data ) );
|
||||
} else {
|
||||
script.text = data;
|
||||
}
|
||||
|
||||
// Use insertBefore instead of appendChild to circumvent an IE6 bug.
|
||||
// This arises when a base node is used (#2709).
|
||||
head.insertBefore( script, head.firstChild );
|
||||
head.removeChild( script );
|
||||
if ( data && rnotwhite.test( data ) ) {
|
||||
// We use execScript on Internet Explorer
|
||||
// We use an anonymous function so that context is window
|
||||
// rather than jQuery in Firefox
|
||||
( window.execScript || function( data ) {
|
||||
window[ "eval" ].call( window, data );
|
||||
} )( data );
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
(function( jQuery ) {
|
||||
|
||||
var // Promise methods
|
||||
promiseMethods = "then done fail isResolved isRejected promise".split( " " ),
|
||||
promiseMethods = "done fail isResolved isRejected promise then always chain".split( " " ),
|
||||
// Static reference to slice
|
||||
sliceDeferred = [].slice;
|
||||
|
||||
|
@ -100,10 +100,38 @@ jQuery.extend({
|
|||
deferred.done( doneCallbacks ).fail( failCallbacks );
|
||||
return this;
|
||||
},
|
||||
always: function() {
|
||||
return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
|
||||
},
|
||||
fail: failDeferred.done,
|
||||
rejectWith: failDeferred.resolveWith,
|
||||
reject: failDeferred.resolve,
|
||||
isRejected: failDeferred.isResolved,
|
||||
// Chain
|
||||
chain: function( fnDone, fnFail ) {
|
||||
return jQuery.Deferred(function( newDefer ) {
|
||||
jQuery.each( {
|
||||
done: [ fnDone, "resolve" ],
|
||||
fail: [ fnFail, "reject" ]
|
||||
}, function( handler, data ) {
|
||||
var fn = data[ 0 ],
|
||||
action = data[ 1 ],
|
||||
returned;
|
||||
if ( jQuery.isFunction( fn ) ) {
|
||||
deferred[ handler ](function() {
|
||||
returned = fn.apply( this, arguments );
|
||||
if ( jQuery.isFunction( returned.promise ) ) {
|
||||
returned.promise().then( newDefer.resolve, newDefer.reject );
|
||||
} else {
|
||||
newDefer[ action ]( returned );
|
||||
}
|
||||
});
|
||||
} else {
|
||||
deferred[ handler ]( newDefer[ action ] );
|
||||
}
|
||||
} );
|
||||
}).promise();
|
||||
},
|
||||
// Get a promise for this deferred
|
||||
// If obj is provided, the promise aspect is added to the object
|
||||
promise: function( obj ) {
|
||||
|
@ -169,4 +197,4 @@ jQuery.extend({
|
|||
}
|
||||
});
|
||||
|
||||
})( jQuery );
|
||||
})( jQuery );
|
17
src/effects.js
vendored
17
src/effects.js
vendored
|
@ -11,7 +11,17 @@ var elemdisplay = {},
|
|||
[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
|
||||
// opacity animations
|
||||
[ "opacity" ]
|
||||
];
|
||||
],
|
||||
fxNow;
|
||||
|
||||
function clearFxNow() {
|
||||
fxNow = undefined;
|
||||
}
|
||||
|
||||
function createFxNow() {
|
||||
setTimeout( clearFxNow, 0 );
|
||||
return ( fxNow = jQuery.now() );
|
||||
}
|
||||
|
||||
jQuery.fn.extend({
|
||||
show: function( speed, easing, callback ) {
|
||||
|
@ -349,7 +359,7 @@ jQuery.fx.prototype = {
|
|||
var self = this,
|
||||
fx = jQuery.fx;
|
||||
|
||||
this.startTime = jQuery.now();
|
||||
this.startTime = fxNow || createFxNow();
|
||||
this.start = from;
|
||||
this.end = to;
|
||||
this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
|
||||
|
@ -394,7 +404,8 @@ jQuery.fx.prototype = {
|
|||
|
||||
// Each step of an animation
|
||||
step: function( gotoEnd ) {
|
||||
var t = jQuery.now(), done = true;
|
||||
var t = fxNow || createFxNow(),
|
||||
done = true;
|
||||
|
||||
if ( gotoEnd || t >= this.options.duration + this.startTime ) {
|
||||
this.now = this.end;
|
||||
|
|
45
src/queue.js
45
src/queue.js
|
@ -28,7 +28,8 @@ jQuery.extend({
|
|||
type = type || "fx";
|
||||
|
||||
var queue = jQuery.queue( elem, type ),
|
||||
fn = queue.shift();
|
||||
fn = queue.shift(),
|
||||
defer;
|
||||
|
||||
// If the fx queue is dequeued, always remove the progress sentinel
|
||||
if ( fn === "inprogress" ) {
|
||||
|
@ -49,6 +50,17 @@ jQuery.extend({
|
|||
|
||||
if ( !queue.length ) {
|
||||
jQuery.removeData( elem, type + "queue", true );
|
||||
// Look if we have observers and resolve if needed
|
||||
if (( defer = jQuery.data( elem, type + "defer", undefined, true ) )) {
|
||||
// Give room for hard-coded callbacks to fire first
|
||||
// and eventually add another animation on the element
|
||||
setTimeout( function() {
|
||||
if ( !jQuery.data( elem, type + "queue", undefined, true ) ) {
|
||||
jQuery.removeData( elem, type + "defer", true );
|
||||
defer.resolve();
|
||||
}
|
||||
}, 0 );
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@ -93,6 +105,37 @@ jQuery.fn.extend({
|
|||
|
||||
clearQueue: function( type ) {
|
||||
return this.queue( type || "fx", [] );
|
||||
},
|
||||
|
||||
// Get a promise resolved when queues of a certain type
|
||||
// are emptied (fx is the type by default)
|
||||
promise: function( type, object ) {
|
||||
if ( typeof type !== "string" ) {
|
||||
object = type;
|
||||
type = undefined;
|
||||
}
|
||||
type = type || "fx";
|
||||
var defer = jQuery.Deferred(),
|
||||
elements = this,
|
||||
i = elements.length,
|
||||
count = 1,
|
||||
deferDataKey = type + "defer",
|
||||
queueDataKey = type + "queue";
|
||||
function resolve() {
|
||||
if ( !( --count ) ) {
|
||||
defer.resolveWith( elements, [ elements ] );
|
||||
}
|
||||
}
|
||||
while( i-- ) {
|
||||
if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) ||
|
||||
jQuery.data( elements[ i ], queueDataKey, undefined, true ) &&
|
||||
jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) {
|
||||
count++;
|
||||
tmp.done( resolve );
|
||||
}
|
||||
}
|
||||
resolve();
|
||||
return defer.promise();
|
||||
}
|
||||
});
|
||||
|
||||
|
|
274
src/support.js
274
src/support.js
|
@ -1,44 +1,58 @@
|
|||
(function( jQuery ) {
|
||||
|
||||
(function() {
|
||||
jQuery.support = (function() {
|
||||
|
||||
jQuery.support = {};
|
||||
var div = document.createElement( "div" ),
|
||||
all,
|
||||
a,
|
||||
select,
|
||||
opt,
|
||||
input,
|
||||
support,
|
||||
fragment,
|
||||
body,
|
||||
bodyStyle,
|
||||
tds,
|
||||
events,
|
||||
eventName,
|
||||
i,
|
||||
isSupported;
|
||||
|
||||
var div = document.createElement("div");
|
||||
|
||||
div.style.display = "none";
|
||||
// Preliminary tests
|
||||
div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
|
||||
|
||||
var all = div.getElementsByTagName("*"),
|
||||
a = div.getElementsByTagName("a")[0],
|
||||
select = document.createElement("select"),
|
||||
opt = select.appendChild( document.createElement("option") ),
|
||||
input = div.getElementsByTagName("input")[0];
|
||||
all = div.getElementsByTagName( "*" );
|
||||
a = div.getElementsByTagName( "a" )[ 0 ];
|
||||
|
||||
// Can't get basic test support
|
||||
if ( !all || !all.length || !a ) {
|
||||
return;
|
||||
return {};
|
||||
}
|
||||
|
||||
jQuery.support = {
|
||||
// First batch of supports tests
|
||||
select = document.createElement( "select" );
|
||||
opt = select.appendChild( document.createElement("option") );
|
||||
input = div.getElementsByTagName( "input" )[ 0 ];
|
||||
|
||||
support = {
|
||||
// IE strips leading whitespace when .innerHTML is used
|
||||
leadingWhitespace: div.firstChild.nodeType === 3,
|
||||
leadingWhitespace: ( div.firstChild.nodeType === 3 ),
|
||||
|
||||
// Make sure that tbody elements aren't automatically inserted
|
||||
// IE will insert them into empty tables
|
||||
tbody: !div.getElementsByTagName("tbody").length,
|
||||
tbody: !div.getElementsByTagName( "tbody" ).length,
|
||||
|
||||
// Make sure that link elements get serialized correctly by innerHTML
|
||||
// This requires a wrapper element in IE
|
||||
htmlSerialize: !!div.getElementsByTagName("link").length,
|
||||
htmlSerialize: !!div.getElementsByTagName( "link" ).length,
|
||||
|
||||
// Get the style information from getAttribute
|
||||
// (IE uses .cssText insted)
|
||||
// (IE uses .cssText instead)
|
||||
style: /red/.test( a.getAttribute("style") ),
|
||||
|
||||
// Make sure that URLs aren't manipulated
|
||||
// (IE normalizes it by default)
|
||||
hrefNormalized: a.getAttribute("href") === "/a",
|
||||
hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
|
||||
|
||||
// Make sure that element opacity exists
|
||||
// (IE uses filter instead)
|
||||
|
@ -59,176 +73,152 @@
|
|||
optSelected: opt.selected,
|
||||
|
||||
// Will be defined later
|
||||
submitBubbles: true,
|
||||
changeBubbles: true,
|
||||
deleteExpando: true,
|
||||
optDisabled: false,
|
||||
checkClone: false,
|
||||
noCloneEvent: true,
|
||||
noCloneChecked: true,
|
||||
boxModel: null,
|
||||
inlineBlockNeedsLayout: false,
|
||||
shrinkWrapBlocks: false,
|
||||
reliableHiddenOffsets: true,
|
||||
reliableMarginRight: true
|
||||
};
|
||||
|
||||
// Make sure checked status is properly cloned
|
||||
input.checked = true;
|
||||
jQuery.support.noCloneChecked = input.cloneNode( true ).checked;
|
||||
support.noCloneChecked = input.cloneNode( true ).checked;
|
||||
|
||||
// Make sure that the options inside disabled selects aren't marked as disabled
|
||||
// (WebKit marks them as diabled)
|
||||
// (WebKit marks them as disabled)
|
||||
select.disabled = true;
|
||||
jQuery.support.optDisabled = !opt.disabled;
|
||||
|
||||
var _scriptEval = null;
|
||||
jQuery.support.scriptEval = function() {
|
||||
if ( _scriptEval === null ) {
|
||||
var root = document.documentElement,
|
||||
script = document.createElement("script"),
|
||||
id = "script" + jQuery.now();
|
||||
|
||||
// Make sure that the execution of code works by injecting a script
|
||||
// tag with appendChild/createTextNode
|
||||
// (IE doesn't support this, fails, and uses .text instead)
|
||||
try {
|
||||
script.appendChild( document.createTextNode( "window." + id + "=1;" ) );
|
||||
} catch(e) {}
|
||||
|
||||
root.insertBefore( script, root.firstChild );
|
||||
|
||||
if ( window[ id ] ) {
|
||||
_scriptEval = true;
|
||||
delete window[ id ];
|
||||
} else {
|
||||
_scriptEval = false;
|
||||
}
|
||||
|
||||
root.removeChild( script );
|
||||
}
|
||||
|
||||
return _scriptEval;
|
||||
};
|
||||
support.optDisabled = !opt.disabled;
|
||||
|
||||
// Test to see if it's possible to delete an expando from an element
|
||||
// Fails in Internet Explorer
|
||||
try {
|
||||
delete div.test;
|
||||
|
||||
} catch(e) {
|
||||
jQuery.support.deleteExpando = false;
|
||||
} catch( e ) {
|
||||
support.deleteExpando = false;
|
||||
}
|
||||
|
||||
if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
|
||||
div.attachEvent("onclick", function click() {
|
||||
div.attachEvent( "onclick", function click() {
|
||||
// Cloning a node shouldn't copy over any
|
||||
// bound event handlers (IE does this)
|
||||
jQuery.support.noCloneEvent = false;
|
||||
div.detachEvent("onclick", click);
|
||||
});
|
||||
div.cloneNode(true).fireEvent("onclick");
|
||||
support.noCloneEvent = false;
|
||||
div.detachEvent( "onclick", click );
|
||||
} );
|
||||
div.cloneNode( true ).fireEvent( "onclick" );
|
||||
}
|
||||
|
||||
div = document.createElement("div");
|
||||
div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
|
||||
|
||||
var fragment = document.createDocumentFragment();
|
||||
fragment = document.createDocumentFragment();
|
||||
fragment.appendChild( div.firstChild );
|
||||
|
||||
// WebKit doesn't clone checked state correctly in fragments
|
||||
jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked;
|
||||
support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked;
|
||||
|
||||
div.innerHTML = "";
|
||||
|
||||
// Figure out if the W3C box model works as expected
|
||||
// document.body must exist before we can do this
|
||||
jQuery(function() {
|
||||
var div = document.createElement("div"),
|
||||
body = document.getElementsByTagName("body")[0];
|
||||
div.style.width = div.style.paddingLeft = "1px";
|
||||
|
||||
// Frameset documents with no body should not run this code
|
||||
if ( !body ) {
|
||||
return;
|
||||
}
|
||||
// We use our own, invisible, body
|
||||
body = document.createElement( "body" );
|
||||
bodyStyle = {
|
||||
visibility: "hidden",
|
||||
width: 0,
|
||||
height: 0,
|
||||
border: 0,
|
||||
margin: 0
|
||||
};
|
||||
for ( i in bodyStyle ) {
|
||||
body.style[ i ] = bodyStyle[ i ];
|
||||
}
|
||||
body.appendChild( div );
|
||||
document.documentElement.appendChild( body );
|
||||
|
||||
div.style.width = div.style.paddingLeft = "1px";
|
||||
body.appendChild( div );
|
||||
jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
|
||||
support.boxModel = div.offsetWidth === 2;
|
||||
|
||||
if ( "zoom" in div.style ) {
|
||||
// Check if natively block-level elements act like inline-block
|
||||
// elements when setting their display to 'inline' and giving
|
||||
// them layout
|
||||
// (IE < 8 does this)
|
||||
div.style.display = "inline";
|
||||
div.style.zoom = 1;
|
||||
jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
|
||||
if ( "zoom" in div.style ) {
|
||||
// Check if natively block-level elements act like inline-block
|
||||
// elements when setting their display to 'inline' and giving
|
||||
// them layout
|
||||
// (IE < 8 does this)
|
||||
div.style.display = "inline";
|
||||
div.style.zoom = 1;
|
||||
support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
|
||||
|
||||
// Check if elements with layout shrink-wrap their children
|
||||
// (IE 6 does this)
|
||||
div.style.display = "";
|
||||
div.innerHTML = "<div style='width:4px;'></div>";
|
||||
jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
|
||||
}
|
||||
// Check if elements with layout shrink-wrap their children
|
||||
// (IE 6 does this)
|
||||
div.style.display = "";
|
||||
div.innerHTML = "<div style='width:4px;'></div>";
|
||||
support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
|
||||
}
|
||||
|
||||
div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
|
||||
var tds = div.getElementsByTagName("td");
|
||||
div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
|
||||
tds = div.getElementsByTagName( "td" );
|
||||
|
||||
// Check if table cells still have offsetWidth/Height when they are set
|
||||
// to display:none and there are still other visible table cells in a
|
||||
// table row; if so, offsetWidth/Height are not reliable for use when
|
||||
// determining if an element has been hidden directly using
|
||||
// display:none (it is still safe to use offsets if a parent element is
|
||||
// hidden; don safety goggles and see bug #4512 for more information).
|
||||
// (only IE 8 fails this test)
|
||||
jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
|
||||
// Check if table cells still have offsetWidth/Height when they are set
|
||||
// to display:none and there are still other visible table cells in a
|
||||
// table row; if so, offsetWidth/Height are not reliable for use when
|
||||
// determining if an element has been hidden directly using
|
||||
// display:none (it is still safe to use offsets if a parent element is
|
||||
// hidden; don safety goggles and see bug #4512 for more information).
|
||||
// (only IE 8 fails this test)
|
||||
isSupported = ( tds[ 0 ].offsetHeight === 0 );
|
||||
|
||||
tds[0].style.display = "";
|
||||
tds[1].style.display = "none";
|
||||
tds[ 0 ].style.display = "";
|
||||
tds[ 1 ].style.display = "none";
|
||||
|
||||
// Check if empty table cells still have offsetWidth/Height
|
||||
// (IE < 8 fail this test)
|
||||
jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
|
||||
div.innerHTML = "";
|
||||
// Check if empty table cells still have offsetWidth/Height
|
||||
// (IE < 8 fail this test)
|
||||
support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
|
||||
div.innerHTML = "";
|
||||
|
||||
// Check if div with explicit width and no margin-right incorrectly
|
||||
// gets computed margin-right based on width of container. For more
|
||||
// info see bug #3333
|
||||
// Fails in WebKit before Feb 2011 nightlies
|
||||
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
|
||||
if ( document.defaultView && document.defaultView.getComputedStyle ) {
|
||||
div.style.width = "1px";
|
||||
div.style.marginRight = "0";
|
||||
jQuery.support.reliableMarginRight = ( parseInt(document.defaultView.getComputedStyle(div, null).marginRight, 10) || 0 ) === 0;
|
||||
}
|
||||
// Check if div with explicit width and no margin-right incorrectly
|
||||
// gets computed margin-right based on width of container. For more
|
||||
// info see bug #3333
|
||||
// Fails in WebKit before Feb 2011 nightlies
|
||||
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
|
||||
if ( document.defaultView && document.defaultView.getComputedStyle ) {
|
||||
div.style.width = "1px";
|
||||
div.style.marginRight = "0";
|
||||
support.reliableMarginRight =
|
||||
( parseInt( document.defaultView.getComputedStyle(div).marginRight, 10 ) || 0 ) === 0;
|
||||
}
|
||||
|
||||
body.removeChild( div ).style.display = "none";
|
||||
div = tds = null;
|
||||
});
|
||||
// Remove the body element we added
|
||||
document.documentElement.removeChild( body );
|
||||
|
||||
// Technique from Juriy Zaytsev
|
||||
// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
|
||||
var eventSupported = function( eventName ) {
|
||||
var el = document.createElement("div");
|
||||
eventName = "on" + eventName;
|
||||
|
||||
// We only care about the case where non-standard event systems
|
||||
// are used, namely in IE. Short-circuiting here helps us to
|
||||
// avoid an eval call (in setAttribute) which can cause CSP
|
||||
// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
|
||||
if ( !el.attachEvent ) {
|
||||
return true;
|
||||
// We only care about the case where non-standard event systems
|
||||
// are used, namely in IE. Short-circuiting here helps us to
|
||||
// avoid an eval call (in setAttribute) which can cause CSP
|
||||
// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
|
||||
if ( div.attachEvent ) {
|
||||
for( i in {
|
||||
submit: 1,
|
||||
change: 1,
|
||||
focusin: 1
|
||||
} ) {
|
||||
eventName = "on" + i;
|
||||
isSupported = ( eventName in div );
|
||||
if ( !isSupported ) {
|
||||
div.setAttribute( eventName, "return;" );
|
||||
isSupported = ( typeof div[ eventName ] === "function" );
|
||||
}
|
||||
support[ i + "Bubbles" ] = isSupported;
|
||||
}
|
||||
|
||||
var isSupported = (eventName in el);
|
||||
if ( !isSupported ) {
|
||||
el.setAttribute(eventName, "return;");
|
||||
isSupported = typeof el[eventName] === "function";
|
||||
}
|
||||
return isSupported;
|
||||
};
|
||||
|
||||
jQuery.support.submitBubbles = eventSupported("submit");
|
||||
jQuery.support.changeBubbles = eventSupported("change");
|
||||
jQuery.support.focusinBubbles = document.attachEvent && eventSupported("focusin");
|
||||
}
|
||||
|
||||
// release memory in IE
|
||||
div = all = a = null;
|
||||
body = div = all = a = tds = undefined;
|
||||
|
||||
return support;
|
||||
})();
|
||||
|
||||
// Keep track of boxModel
|
||||
jQuery.boxModel = jQuery.support.boxModel;
|
||||
|
||||
})( jQuery );
|
||||
|
|
|
@ -172,6 +172,26 @@ test("selector state", function() {
|
|||
);
|
||||
});
|
||||
|
||||
test( "globalEval", function() {
|
||||
|
||||
expect( 3 );
|
||||
|
||||
jQuery.globalEval( "var globalEvalTest = true;" );
|
||||
ok( window.globalEvalTest, "Test variable declarations are global" );
|
||||
|
||||
window.globalEvalTest = false;
|
||||
|
||||
jQuery.globalEval( "globalEvalTest = true;" );
|
||||
ok( window.globalEvalTest, "Test variable assignments are global" );
|
||||
|
||||
window.globalEvalTest = false;
|
||||
|
||||
jQuery.globalEval( "this.globalEvalTest = true;" );
|
||||
ok( window.globalEvalTest, "Test context (this) is the window object" );
|
||||
|
||||
window.globalEvalTest = undefined;
|
||||
});
|
||||
|
||||
if ( !isLocal ) {
|
||||
test("browser", function() {
|
||||
stop();
|
||||
|
|
|
@ -1,153 +1,273 @@
|
|||
module("deferred", { teardown: moduleTeardown });
|
||||
|
||||
test("jQuery._Deferred()", function() {
|
||||
jQuery.each( [ "", " - new operator" ], function( _, withNew ) {
|
||||
|
||||
expect( 11 );
|
||||
|
||||
var deferred,
|
||||
object,
|
||||
test;
|
||||
|
||||
deferred = jQuery._Deferred();
|
||||
|
||||
test = false;
|
||||
|
||||
deferred.done( function( value ) {
|
||||
equals( value , "value" , "Test pre-resolve callback" );
|
||||
test = true;
|
||||
} );
|
||||
|
||||
deferred.resolve( "value" );
|
||||
|
||||
ok( test , "Test pre-resolve callbacks called right away" );
|
||||
|
||||
test = false;
|
||||
|
||||
deferred.done( function( value ) {
|
||||
equals( value , "value" , "Test post-resolve callback" );
|
||||
test = true;
|
||||
} );
|
||||
|
||||
ok( test , "Test post-resolve callbacks called right away" );
|
||||
|
||||
deferred.cancel();
|
||||
|
||||
test = true;
|
||||
|
||||
deferred.done( function() {
|
||||
ok( false , "Cancel was ignored" );
|
||||
test = false;
|
||||
} );
|
||||
|
||||
ok( test , "Test cancel" );
|
||||
|
||||
deferred = jQuery._Deferred().resolve();
|
||||
|
||||
try {
|
||||
deferred.done( function() {
|
||||
throw "Error";
|
||||
} , function() {
|
||||
ok( true , "Test deferred do not cancel on exception" );
|
||||
} );
|
||||
} catch( e ) {
|
||||
strictEqual( e , "Error" , "Test deferred propagates exceptions");
|
||||
deferred.done();
|
||||
function createDeferred() {
|
||||
return withNew ? new jQuery._Deferred() : jQuery._Deferred();
|
||||
}
|
||||
|
||||
test = "";
|
||||
deferred = jQuery._Deferred().done( function() {
|
||||
test("jQuery._Deferred" + withNew, function() {
|
||||
|
||||
test += "A";
|
||||
expect( 11 );
|
||||
|
||||
}, function() {
|
||||
var deferred,
|
||||
object,
|
||||
test;
|
||||
|
||||
test += "B";
|
||||
deferred = createDeferred();
|
||||
|
||||
} ).resolve();
|
||||
test = false;
|
||||
|
||||
strictEqual( test , "AB" , "Test multiple done parameters" );
|
||||
deferred.done( function( value ) {
|
||||
equals( value , "value" , "Test pre-resolve callback" );
|
||||
test = true;
|
||||
} );
|
||||
|
||||
test = "";
|
||||
deferred.resolve( "value" );
|
||||
|
||||
deferred.done( function() {
|
||||
ok( test , "Test pre-resolve callbacks called right away" );
|
||||
|
||||
test = false;
|
||||
|
||||
deferred.done( function( value ) {
|
||||
equals( value , "value" , "Test post-resolve callback" );
|
||||
test = true;
|
||||
} );
|
||||
|
||||
ok( test , "Test post-resolve callbacks called right away" );
|
||||
|
||||
deferred.cancel();
|
||||
|
||||
test = true;
|
||||
|
||||
deferred.done( function() {
|
||||
ok( false , "Cancel was ignored" );
|
||||
test = false;
|
||||
} );
|
||||
|
||||
ok( test , "Test cancel" );
|
||||
|
||||
deferred = createDeferred().resolve();
|
||||
|
||||
try {
|
||||
deferred.done( function() {
|
||||
throw "Error";
|
||||
} , function() {
|
||||
ok( true , "Test deferred do not cancel on exception" );
|
||||
} );
|
||||
} catch( e ) {
|
||||
strictEqual( e , "Error" , "Test deferred propagates exceptions");
|
||||
deferred.done();
|
||||
}
|
||||
|
||||
test = "";
|
||||
deferred = createDeferred().done( function() {
|
||||
|
||||
test += "A";
|
||||
|
||||
}, function() {
|
||||
|
||||
test += "B";
|
||||
|
||||
} ).resolve();
|
||||
|
||||
strictEqual( test , "AB" , "Test multiple done parameters" );
|
||||
|
||||
test = "";
|
||||
|
||||
deferred.done( function() {
|
||||
|
||||
test += "C";
|
||||
deferred.done( function() {
|
||||
|
||||
test += "C";
|
||||
|
||||
} );
|
||||
|
||||
test += "A";
|
||||
|
||||
}, function() {
|
||||
|
||||
test += "B";
|
||||
} );
|
||||
|
||||
test += "A";
|
||||
strictEqual( test , "ABC" , "Test done callbacks order" );
|
||||
|
||||
}, function() {
|
||||
deferred = createDeferred();
|
||||
|
||||
test += "B";
|
||||
deferred.resolveWith( jQuery , [ document ] ).done( function( doc ) {
|
||||
ok( this === jQuery && arguments.length === 1 && doc === document , "Test fire context & args" );
|
||||
});
|
||||
|
||||
// #8421
|
||||
deferred = createDeferred();
|
||||
deferred.resolveWith().done(function() {
|
||||
ok( true, "Test resolveWith can be called with no argument" );
|
||||
});
|
||||
});
|
||||
} );
|
||||
|
||||
jQuery.each( [ "", " - new operator" ], function( _, withNew ) {
|
||||
|
||||
function createDeferred( fn ) {
|
||||
return withNew ? new jQuery.Deferred( fn ) : jQuery.Deferred( fn );
|
||||
}
|
||||
|
||||
test("jQuery.Deferred" + withNew, function() {
|
||||
|
||||
expect( 8 );
|
||||
|
||||
createDeferred().resolve().then( function() {
|
||||
ok( true , "Success on resolve" );
|
||||
ok( this.isResolved(), "Deferred is resolved" );
|
||||
}, function() {
|
||||
ok( false , "Error on resolve" );
|
||||
}).always( function() {
|
||||
ok( true , "Always callback on resolve" );
|
||||
});
|
||||
|
||||
createDeferred().reject().then( function() {
|
||||
ok( false , "Success on reject" );
|
||||
}, function() {
|
||||
ok( true , "Error on reject" );
|
||||
ok( this.isRejected(), "Deferred is rejected" );
|
||||
}).always( function() {
|
||||
ok( true , "Always callback on reject" );
|
||||
});
|
||||
|
||||
createDeferred( function( defer ) {
|
||||
ok( this === defer , "Defer passed as this & first argument" );
|
||||
this.resolve( "done" );
|
||||
}).then( function( value ) {
|
||||
strictEqual( value , "done" , "Passed function executed" );
|
||||
});
|
||||
});
|
||||
} );
|
||||
|
||||
test( "jQuery.Deferred.chain - filtering (done)", function() {
|
||||
|
||||
expect(3);
|
||||
|
||||
var defer = jQuery.Deferred(),
|
||||
chained = defer.chain(function( a, b ) {
|
||||
return a * b;
|
||||
}),
|
||||
value1,
|
||||
value2,
|
||||
value3;
|
||||
|
||||
chained.done(function( result ) {
|
||||
value3 = result;
|
||||
});
|
||||
|
||||
defer.done(function( a, b ) {
|
||||
value1 = a;
|
||||
value2 = b;
|
||||
});
|
||||
|
||||
defer.resolve( 2, 3 );
|
||||
|
||||
strictEqual( value1, 2, "first resolve value ok" );
|
||||
strictEqual( value2, 3, "second resolve value ok" );
|
||||
strictEqual( value3, 6, "result of filter ok" );
|
||||
|
||||
jQuery.Deferred().reject().chain(function() {
|
||||
ok( false, "chain should not be called on reject" );
|
||||
});
|
||||
});
|
||||
|
||||
test( "jQuery.Deferred.chain - filtering (fail)", function() {
|
||||
|
||||
expect(3);
|
||||
|
||||
var defer = jQuery.Deferred(),
|
||||
chained = defer.chain( null, function( a, b ) {
|
||||
return a * b;
|
||||
} ),
|
||||
value1,
|
||||
value2,
|
||||
value3;
|
||||
|
||||
chained.fail(function( result ) {
|
||||
value3 = result;
|
||||
});
|
||||
|
||||
defer.fail(function( a, b ) {
|
||||
value1 = a;
|
||||
value2 = b;
|
||||
});
|
||||
|
||||
defer.reject( 2, 3 );
|
||||
|
||||
strictEqual( value1, 2, "first reject value ok" );
|
||||
strictEqual( value2, 3, "second reject value ok" );
|
||||
strictEqual( value3, 6, "result of filter ok" );
|
||||
|
||||
jQuery.Deferred().resolve().chain( null, function() {
|
||||
ok( false, "chain should not be called on resolve" );
|
||||
} );
|
||||
|
||||
strictEqual( test , "ABC" , "Test done callbacks order" );
|
||||
|
||||
deferred = jQuery._Deferred();
|
||||
|
||||
deferred.resolveWith( jQuery , [ document ] ).done( function( doc ) {
|
||||
ok( this === jQuery && arguments.length === 1 && doc === document , "Test fire context & args" );
|
||||
});
|
||||
|
||||
// #8421
|
||||
deferred = jQuery._Deferred();
|
||||
deferred.resolveWith().done(function() {
|
||||
ok( true, "Test resolveWith can be called with no argument" );
|
||||
});
|
||||
});
|
||||
|
||||
test("jQuery.Deferred()", function() {
|
||||
test( "jQuery.Deferred.chain - deferred (done)", function() {
|
||||
|
||||
expect( 10 );
|
||||
expect(3);
|
||||
|
||||
jQuery.Deferred( function( defer ) {
|
||||
strictEqual( this , defer , "Defer passed as this & first argument" );
|
||||
this.resolve( "done" );
|
||||
}).then( function( value ) {
|
||||
strictEqual( value , "done" , "Passed function executed" );
|
||||
var defer = jQuery.Deferred(),
|
||||
chained = defer.chain(function( a, b ) {
|
||||
return jQuery.Deferred(function( defer ) {
|
||||
defer.reject( a * b );
|
||||
});
|
||||
}),
|
||||
value1,
|
||||
value2,
|
||||
value3;
|
||||
|
||||
chained.fail(function( result ) {
|
||||
value3 = result;
|
||||
});
|
||||
|
||||
jQuery.Deferred().resolve().then( function() {
|
||||
ok( true , "Success on resolve" );
|
||||
}, function() {
|
||||
ok( false , "Error on resolve" );
|
||||
defer.done(function( a, b ) {
|
||||
value1 = a;
|
||||
value2 = b;
|
||||
});
|
||||
|
||||
jQuery.Deferred().reject().then( function() {
|
||||
ok( false , "Success on reject" );
|
||||
}, function() {
|
||||
ok( true , "Error on reject" );
|
||||
});
|
||||
defer.resolve( 2, 3 );
|
||||
|
||||
( new jQuery.Deferred( function( defer ) {
|
||||
strictEqual( this , defer , "Defer passed as this & first argument (new)" );
|
||||
this.resolve( "done" );
|
||||
}) ).then( function( value ) {
|
||||
strictEqual( value , "done" , "Passed function executed (new)" );
|
||||
});
|
||||
|
||||
( new jQuery.Deferred() ).resolve().then( function() {
|
||||
ok( true , "Success on resolve (new)" );
|
||||
}, function() {
|
||||
ok( false , "Error on resolve (new)" );
|
||||
});
|
||||
|
||||
( new jQuery.Deferred() ).reject().then( function() {
|
||||
ok( false , "Success on reject (new)" );
|
||||
}, function() {
|
||||
ok( true , "Error on reject (new)" );
|
||||
});
|
||||
|
||||
var tmp = jQuery.Deferred();
|
||||
|
||||
strictEqual( tmp.promise() , tmp.promise() , "Test deferred always return same promise" );
|
||||
strictEqual( tmp.promise() , tmp.promise().promise() , "Test deferred's promise always return same promise as deferred" );
|
||||
strictEqual( value1, 2, "first resolve value ok" );
|
||||
strictEqual( value2, 3, "second resolve value ok" );
|
||||
strictEqual( value3, 6, "result of filter ok" );
|
||||
});
|
||||
|
||||
test("jQuery.when()", function() {
|
||||
test( "jQuery.Deferred.chain - deferred (fail)", function() {
|
||||
|
||||
expect(3);
|
||||
|
||||
var defer = jQuery.Deferred(),
|
||||
chained = defer.chain( null, function( a, b ) {
|
||||
return jQuery.Deferred(function( defer ) {
|
||||
defer.resolve( a * b );
|
||||
});
|
||||
} ),
|
||||
value1,
|
||||
value2,
|
||||
value3;
|
||||
|
||||
chained.done(function( result ) {
|
||||
value3 = result;
|
||||
});
|
||||
|
||||
defer.fail(function( a, b ) {
|
||||
value1 = a;
|
||||
value2 = b;
|
||||
});
|
||||
|
||||
defer.reject( 2, 3 );
|
||||
|
||||
strictEqual( value1, 2, "first reject value ok" );
|
||||
strictEqual( value2, 3, "second reject value ok" );
|
||||
strictEqual( value3, 6, "result of filter ok" );
|
||||
});
|
||||
|
||||
test( "jQuery.when" , function() {
|
||||
|
||||
expect( 23 );
|
||||
|
||||
|
@ -166,57 +286,63 @@ test("jQuery.when()", function() {
|
|||
|
||||
} , function( message , value ) {
|
||||
|
||||
ok( jQuery.isFunction( jQuery.when( value ).then( function( resolveValue ) {
|
||||
ok( jQuery.isFunction( jQuery.when( value ).done(function( resolveValue ) {
|
||||
strictEqual( resolveValue , value , "Test the promise was resolved with " + message );
|
||||
} ).promise ) , "Test " + message + " triggers the creation of a new Promise" );
|
||||
}).promise ) , "Test " + message + " triggers the creation of a new Promise" );
|
||||
|
||||
} );
|
||||
|
||||
ok( jQuery.isFunction( jQuery.when().then( function( resolveValue ) {
|
||||
ok( jQuery.isFunction( jQuery.when().done(function( resolveValue ) {
|
||||
strictEqual( resolveValue , undefined , "Test the promise was resolved with no parameter" );
|
||||
} ).promise ) , "Test calling when with no parameter triggers the creation of a new Promise" );
|
||||
}).promise ) , "Test calling when with no parameter triggers the creation of a new Promise" );
|
||||
|
||||
var cache, i;
|
||||
|
||||
for( i = 1 ; i < 4 ; i++ ) {
|
||||
jQuery.when( cache || jQuery.Deferred( function() {
|
||||
this.resolve( i );
|
||||
}) ).then( function( value ) {
|
||||
}) ).done(function( value ) {
|
||||
strictEqual( value , 1 , "Function executed" + ( i > 1 ? " only once" : "" ) );
|
||||
cache = value;
|
||||
}, function() {
|
||||
ok( false , "Fail called" );
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
test("jQuery.when() - joined", function() {
|
||||
test("jQuery.when - joined", function() {
|
||||
|
||||
expect(8);
|
||||
expect(25);
|
||||
|
||||
jQuery.when( 1, 2, 3 ).done( function( a, b, c ) {
|
||||
strictEqual( a , 1 , "Test first param is first resolved value - non-observables" );
|
||||
strictEqual( b , 2 , "Test second param is second resolved value - non-observables" );
|
||||
strictEqual( c , 3 , "Test third param is third resolved value - non-observables" );
|
||||
}).fail( function() {
|
||||
ok( false , "Test the created deferred was resolved - non-observables");
|
||||
});
|
||||
var deferreds = {
|
||||
value: 1,
|
||||
success: jQuery.Deferred().resolve( 1 ),
|
||||
error: jQuery.Deferred().reject( 0 ),
|
||||
futureSuccess: jQuery.Deferred(),
|
||||
futureError: jQuery.Deferred()
|
||||
},
|
||||
willSucceed = {
|
||||
value: true,
|
||||
success: true,
|
||||
error: false,
|
||||
futureSuccess: true,
|
||||
futureError: false
|
||||
};
|
||||
|
||||
var successDeferred = jQuery.Deferred().resolve( 1 , 2 , 3 ),
|
||||
errorDeferred = jQuery.Deferred().reject( "error" , "errorParam" );
|
||||
|
||||
jQuery.when( 1 , successDeferred , 3 ).done( function( a, b, c ) {
|
||||
strictEqual( a , 1 , "Test first param is first resolved value - resolved observable" );
|
||||
same( b , [ 1 , 2 , 3 ] , "Test second param is second resolved value - resolved observable" );
|
||||
strictEqual( c , 3 , "Test third param is third resolved value - resolved observable" );
|
||||
}).fail( function() {
|
||||
ok( false , "Test the created deferred was resolved - resolved observable");
|
||||
});
|
||||
|
||||
jQuery.when( 1 , errorDeferred , 3 ).done( function() {
|
||||
ok( false , "Test the created deferred was rejected - rejected observable");
|
||||
}).fail( function( error , errorParam ) {
|
||||
strictEqual( error , "error" , "Test first param is first rejected value - rejected observable" );
|
||||
strictEqual( errorParam , "errorParam" , "Test second param is second rejected value - rejected observable" );
|
||||
});
|
||||
jQuery.each( deferreds, function( id1, defer1 ) {
|
||||
jQuery.each( deferreds, function( id2, defer2 ) {
|
||||
var shouldResolve = willSucceed[ id1 ] && willSucceed[ id2 ],
|
||||
expected = shouldResolve ? [ 1, 1 ] : [ 0, undefined ],
|
||||
code = id1 + "/" + id2;
|
||||
jQuery.when( defer1, defer2 ).done(function( a, b ) {
|
||||
if ( shouldResolve ) {
|
||||
same( [ a, b ], expected, code + " => resolve" );
|
||||
}
|
||||
}).fail(function( a, b ) {
|
||||
if ( !shouldResolve ) {
|
||||
same( [ a, b ], expected, code + " => resolve" );
|
||||
}
|
||||
});
|
||||
} );
|
||||
} );
|
||||
deferreds.futureSuccess.resolve( 1 );
|
||||
deferreds.futureError.reject( 0 );
|
||||
});
|
||||
|
|
41
test/unit/effects.js
vendored
41
test/unit/effects.js
vendored
|
@ -717,59 +717,64 @@ jQuery.each( {
|
|||
|
||||
var anim = { width: t_w, height: t_h, opacity: t_o };
|
||||
|
||||
elem.animate(anim, 50, function(){
|
||||
elem.animate(anim, 50);
|
||||
|
||||
jQuery.when( elem ).done(function( elem ){
|
||||
|
||||
elem = elem[ 0 ];
|
||||
|
||||
if ( t_w == "show" )
|
||||
equals( this.style.display, "block", "Showing, display should block: " + this.style.display);
|
||||
equals( elem.style.display, "block", "Showing, display should block: " + elem.style.display);
|
||||
|
||||
if ( t_w == "hide"||t_w == "show" )
|
||||
ok(f_w === "" ? this.style.width === f_w : this.style.width.indexOf(f_w) === 0, "Width must be reset to " + f_w + ": " + this.style.width);
|
||||
ok(f_w === "" ? elem.style.width === f_w : elem.style.width.indexOf(f_w) === 0, "Width must be reset to " + f_w + ": " + elem.style.width);
|
||||
|
||||
if ( t_h == "hide"||t_h == "show" )
|
||||
ok(f_h === "" ? this.style.height === f_h : this.style.height.indexOf(f_h) === 0, "Height must be reset to " + f_h + ": " + this.style.height);
|
||||
ok(f_h === "" ? elem.style.height === f_h : elem.style.height.indexOf(f_h) === 0, "Height must be reset to " + f_h + ": " + elem.style.height);
|
||||
|
||||
var cur_o = jQuery.style(this, "opacity");
|
||||
var cur_o = jQuery.style(elem, "opacity");
|
||||
|
||||
if ( t_o == "hide" || t_o == "show" )
|
||||
equals(cur_o, f_o, "Opacity must be reset to " + f_o + ": " + cur_o);
|
||||
|
||||
if ( t_w == "hide" )
|
||||
equals(this.style.display, "none", "Hiding, display should be none: " + this.style.display);
|
||||
equals(elem.style.display, "none", "Hiding, display should be none: " + elem.style.display);
|
||||
|
||||
if ( t_o.constructor == Number ) {
|
||||
equals(cur_o, t_o, "Final opacity should be " + t_o + ": " + cur_o);
|
||||
|
||||
ok(jQuery.css(this, "opacity") != "" || cur_o == t_o, "Opacity should be explicitly set to " + t_o + ", is instead: " + cur_o);
|
||||
ok(jQuery.css(elem, "opacity") != "" || cur_o == t_o, "Opacity should be explicitly set to " + t_o + ", is instead: " + cur_o);
|
||||
}
|
||||
|
||||
if ( t_w.constructor == Number ) {
|
||||
equals(this.style.width, t_w + "px", "Final width should be " + t_w + ": " + this.style.width);
|
||||
equals(elem.style.width, t_w + "px", "Final width should be " + t_w + ": " + elem.style.width);
|
||||
|
||||
var cur_w = jQuery.css(this,"width");
|
||||
var cur_w = jQuery.css(elem,"width");
|
||||
|
||||
ok(this.style.width != "" || cur_w == t_w, "Width should be explicitly set to " + t_w + ", is instead: " + cur_w);
|
||||
ok(elem.style.width != "" || cur_w == t_w, "Width should be explicitly set to " + t_w + ", is instead: " + cur_w);
|
||||
}
|
||||
|
||||
if ( t_h.constructor == Number ) {
|
||||
equals(this.style.height, t_h + "px", "Final height should be " + t_h + ": " + this.style.height);
|
||||
equals(elem.style.height, t_h + "px", "Final height should be " + t_h + ": " + elem.style.height);
|
||||
|
||||
var cur_h = jQuery.css(this,"height");
|
||||
var cur_h = jQuery.css(elem,"height");
|
||||
|
||||
ok(this.style.height != "" || cur_h == t_h, "Height should be explicitly set to " + t_h + ", is instead: " + cur_w);
|
||||
ok(elem.style.height != "" || cur_h == t_h, "Height should be explicitly set to " + t_h + ", is instead: " + cur_w);
|
||||
}
|
||||
|
||||
if ( t_h == "show" ) {
|
||||
var old_h = jQuery.css(this, "height");
|
||||
jQuery(this).append("<br/>Some more text<br/>and some more...");
|
||||
var old_h = jQuery.css(elem, "height");
|
||||
jQuery(elem).append("<br/>Some more text<br/>and some more...");
|
||||
|
||||
if ( /Auto/.test( fn ) ) {
|
||||
notEqual(jQuery.css(this, "height"), old_h, "Make sure height is auto.");
|
||||
notEqual(jQuery.css(elem, "height"), old_h, "Make sure height is auto.");
|
||||
} else {
|
||||
equals(jQuery.css(this, "height"), old_h, "Make sure height is not auto.");
|
||||
equals(jQuery.css(elem, "height"), old_h, "Make sure height is not auto.");
|
||||
}
|
||||
}
|
||||
|
||||
// manually remove generated element
|
||||
jQuery(this).remove();
|
||||
jQuery(elem).remove();
|
||||
|
||||
start();
|
||||
});
|
||||
|
|
Loading…
Reference in a new issue