Merge branch 'master' into attrhooks.1.6v2
This commit is contained in:
commit
c10a76ec71
83
README.md
83
README.md
|
@ -56,6 +56,89 @@ Sometimes, the various git repositories get into an inconsistent state where bui
|
||||||
(usually this results in the jquery.js or jquery.min.js being 0 bytes). If this happens, run `make clean`, then
|
(usually this results in the jquery.js or jquery.min.js being 0 bytes). If this happens, run `make clean`, then
|
||||||
run `make` again.
|
run `make` again.
|
||||||
|
|
||||||
|
Git for dummies
|
||||||
|
---------------
|
||||||
|
|
||||||
|
As the source code is handled by the version control system Git, it's useful to know some features used.
|
||||||
|
|
||||||
|
### Submodules ###
|
||||||
|
|
||||||
|
The repository uses submodules, which normally are handles directly by the Makefile, but sometimes you want to
|
||||||
|
be able to work with them manually.
|
||||||
|
|
||||||
|
Following are the steps to manually get the submodules:
|
||||||
|
|
||||||
|
1. `git clone https://github.com/jquery/jquery.git`
|
||||||
|
2. `git submodule init`
|
||||||
|
3. `git submodule update`
|
||||||
|
|
||||||
|
Or:
|
||||||
|
|
||||||
|
1. `git clone https://github.com/jquery/jquery.git`
|
||||||
|
2. `git submodule update --init`
|
||||||
|
|
||||||
|
Or:
|
||||||
|
|
||||||
|
1. `git clone --recursive https://github.com/jquery/jquery.git`
|
||||||
|
|
||||||
|
If you want to work inside a submodule, it is possible, but first you need to checkout a branch:
|
||||||
|
|
||||||
|
1. `cd src/sizzle`
|
||||||
|
2. `git checkout master`
|
||||||
|
|
||||||
|
After you've commited your changes to the submodule, you'll update the jquery project to point to the new commit,
|
||||||
|
but remember to push the submodule changes before pushing the new jquery commit:
|
||||||
|
|
||||||
|
1. `cd src/sizzle`
|
||||||
|
2. `git push origin master`
|
||||||
|
3. `cd ..`
|
||||||
|
4. `git add src/sizzle`
|
||||||
|
5. `git commit`
|
||||||
|
|
||||||
|
The makefile has some targets to simplify submodule handling:
|
||||||
|
|
||||||
|
#### `make update_submodules` ####
|
||||||
|
|
||||||
|
checks out the commit pointed to byu jquery, but merges your local changes, if any. This target is executed
|
||||||
|
when you are doing a normal `make`.
|
||||||
|
|
||||||
|
#### `make pull_submodules` ####
|
||||||
|
|
||||||
|
updates the content of the submoduels to what is probably the latest upstream code
|
||||||
|
|
||||||
|
#### `make pull` ####
|
||||||
|
|
||||||
|
make a `make pull_submodules` and after that a `git pull`. if you have no remote tracking in your master branch, you can
|
||||||
|
execute this command as `make pull REMOTE=origin BRANCH=master` instead.
|
||||||
|
|
||||||
|
### cleaning ###
|
||||||
|
|
||||||
|
If you want to purge your working directory back to the status of upstream, following commands can be used (remember everything you've worked on is gone after these):
|
||||||
|
|
||||||
|
1. `git reset --hard upstream/master`
|
||||||
|
2. `git clean -fdx`
|
||||||
|
|
||||||
|
### rebasing ###
|
||||||
|
|
||||||
|
For feature/topic branches, you should always used the `--rebase` flag to `git pull`, or if you are usually handling many temporary "to be in a github pull request" branches, run following to automate this:
|
||||||
|
|
||||||
|
* `git config branch.autosetuprebase local` (see `man git-config` for more information)
|
||||||
|
|
||||||
|
### handling merge conflicts ###
|
||||||
|
|
||||||
|
If you're getting merge conflicts when merging, instead of editing the conflicted files manually, you can use the feature
|
||||||
|
`git mergetool`. Even though the default tool `xxdiff` looks awful/old, it's rather useful.
|
||||||
|
|
||||||
|
Following are some commands that can be used there:
|
||||||
|
|
||||||
|
* `Ctrl + Alt + M` - automerge as much as possible
|
||||||
|
* `b` - jump to next merge conflict
|
||||||
|
* `s` - change the order of the conflicted lines
|
||||||
|
* `u` - undo an merge
|
||||||
|
* `left mouse button` - mark a block to be the winner
|
||||||
|
* `middle mouse button` - mark a line to be the winner
|
||||||
|
* `Ctrl + S` - save
|
||||||
|
* `Ctrl + Q` - quit
|
||||||
|
|
||||||
Questions?
|
Questions?
|
||||||
----------
|
----------
|
||||||
|
|
|
@ -53,7 +53,7 @@ jQuery.ajaxTransport( "script", function(s) {
|
||||||
// Attach handlers for all browsers
|
// Attach handlers for all browsers
|
||||||
script.onload = script.onreadystatechange = function( _, isAbort ) {
|
script.onload = script.onreadystatechange = function( _, isAbort ) {
|
||||||
|
|
||||||
if ( !script.readyState || /loaded|complete/.test( script.readyState ) ) {
|
if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) {
|
||||||
|
|
||||||
// Handle memory leak in IE
|
// Handle memory leak in IE
|
||||||
script.onload = script.onreadystatechange = null;
|
script.onload = script.onreadystatechange = null;
|
||||||
|
|
|
@ -34,6 +34,20 @@ jQuery.fn.extend({
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
prop: function( name, value ) {
|
||||||
|
return jQuery.access( this, name, value, true, jQuery.prop );
|
||||||
|
},
|
||||||
|
|
||||||
|
removeProp: function( name ) {
|
||||||
|
return this.each(function() {
|
||||||
|
// try/catch handles cases where IE balks (such as removing a property on window)
|
||||||
|
try {
|
||||||
|
this[ name ] = undefined;
|
||||||
|
delete this[ name ];
|
||||||
|
} catch( e ) {}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
addClass: function( value ) {
|
addClass: function( value ) {
|
||||||
if ( jQuery.isFunction( value ) ) {
|
if ( jQuery.isFunction( value ) ) {
|
||||||
return this.each(function(i) {
|
return this.each(function(i) {
|
||||||
|
|
74
src/core.js
74
src/core.js
|
@ -17,7 +17,7 @@ var jQuery = function( selector, context ) {
|
||||||
|
|
||||||
// A simple way to check for HTML strings or ID strings
|
// A simple way to check for HTML strings or ID strings
|
||||||
// (both of which we optimize for)
|
// (both of which we optimize for)
|
||||||
quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/,
|
quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/,
|
||||||
|
|
||||||
// Check if a string has a non-whitespace character in it
|
// Check if a string has a non-whitespace character in it
|
||||||
rnotwhite = /\S/,
|
rnotwhite = /\S/,
|
||||||
|
@ -96,7 +96,12 @@ jQuery.fn = jQuery.prototype = {
|
||||||
// Handle HTML strings
|
// Handle HTML strings
|
||||||
if ( typeof selector === "string" ) {
|
if ( typeof selector === "string" ) {
|
||||||
// Are we dealing with HTML string or an ID?
|
// Are we dealing with HTML string or an ID?
|
||||||
|
if ( selector.length > 1024 ) {
|
||||||
|
// Assume very large strings are HTML and skip the regex check
|
||||||
|
match = [ null, selector, null ];
|
||||||
|
} else {
|
||||||
match = quickExpr.exec( selector );
|
match = quickExpr.exec( selector );
|
||||||
|
}
|
||||||
|
|
||||||
// Verify a match, and that no context was specified for #id
|
// Verify a match, and that no context was specified for #id
|
||||||
if ( match && (match[1] || !context) ) {
|
if ( match && (match[1] || !context) ) {
|
||||||
|
@ -369,15 +374,19 @@ jQuery.extend({
|
||||||
// the ready event fires. See #6781
|
// the ready event fires. See #6781
|
||||||
readyWait: 1,
|
readyWait: 1,
|
||||||
|
|
||||||
|
// Hold (or release) the ready event
|
||||||
|
holdReady: function( hold ) {
|
||||||
|
if ( hold ) {
|
||||||
|
jQuery.readyWait++;
|
||||||
|
} else {
|
||||||
|
jQuery.ready( true );
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
// Handle when the DOM is ready
|
// Handle when the DOM is ready
|
||||||
ready: function( wait ) {
|
ready: function( wait ) {
|
||||||
// A third-party is pushing the ready event forwards
|
// Either a released hold or an DOMready/load event and not yet ready
|
||||||
if ( wait === true ) {
|
if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) {
|
||||||
jQuery.readyWait--;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Make sure that the DOM is not already loaded
|
|
||||||
if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) {
|
|
||||||
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
|
// Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443).
|
||||||
if ( !document.body ) {
|
if ( !document.body ) {
|
||||||
return setTimeout( jQuery.ready, 1 );
|
return setTimeout( jQuery.ready, 1 );
|
||||||
|
@ -515,20 +524,21 @@ jQuery.extend({
|
||||||
// Make sure leading/trailing whitespace is removed (IE can't handle it)
|
// Make sure leading/trailing whitespace is removed (IE can't handle it)
|
||||||
data = jQuery.trim( data );
|
data = jQuery.trim( data );
|
||||||
|
|
||||||
|
// Attempt to parse using the native JSON parser first
|
||||||
|
if ( window.JSON && window.JSON.parse ) {
|
||||||
|
return window.JSON.parse( data );
|
||||||
|
}
|
||||||
|
|
||||||
// Make sure the incoming data is actual JSON
|
// Make sure the incoming data is actual JSON
|
||||||
// Logic borrowed from http://json.org/json2.js
|
// Logic borrowed from http://json.org/json2.js
|
||||||
if ( rvalidchars.test( data.replace( rvalidescape, "@" )
|
if ( rvalidchars.test( data.replace( rvalidescape, "@" )
|
||||||
.replace( rvalidtokens, "]" )
|
.replace( rvalidtokens, "]" )
|
||||||
.replace( rvalidbraces, "")) ) {
|
.replace( rvalidbraces, "")) ) {
|
||||||
|
|
||||||
// Try to use the native JSON parser first
|
return (new Function( "return " + data ))();
|
||||||
return window.JSON && window.JSON.parse ?
|
|
||||||
window.JSON.parse( data ) :
|
|
||||||
(new Function("return " + data))();
|
|
||||||
|
|
||||||
} else {
|
|
||||||
jQuery.error( "Invalid JSON: " + data );
|
|
||||||
}
|
}
|
||||||
|
jQuery.error( "Invalid JSON: " + data );
|
||||||
},
|
},
|
||||||
|
|
||||||
// Cross-browser xml parsing
|
// Cross-browser xml parsing
|
||||||
|
@ -555,24 +565,17 @@ jQuery.extend({
|
||||||
|
|
||||||
noop: function() {},
|
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 ) {
|
globalEval: function( data ) {
|
||||||
if ( data && rnotwhite.test( data ) ) {
|
if ( data && rnotwhite.test( data ) ) {
|
||||||
// Inspired by code by Andrea Giammarchi
|
// We use execScript on Internet Explorer
|
||||||
// http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html
|
// We use an anonymous function so that context is window
|
||||||
var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement,
|
// rather than jQuery in Firefox
|
||||||
script = document.createElement( "script" );
|
( window.execScript || function( data ) {
|
||||||
|
window[ "eval" ].call( window, data );
|
||||||
if ( jQuery.support.scriptEval() ) {
|
} )( data );
|
||||||
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 );
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -655,8 +658,9 @@ jQuery.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
inArray: function( elem, array ) {
|
inArray: function( elem, array ) {
|
||||||
if ( array.indexOf ) {
|
|
||||||
return array.indexOf( elem );
|
if ( indexOf ) {
|
||||||
|
return indexOf.call( array, elem );
|
||||||
}
|
}
|
||||||
|
|
||||||
for ( var i = 0, length = array.length; i < length; i++ ) {
|
for ( var i = 0, length = array.length; i < length; i++ ) {
|
||||||
|
@ -840,12 +844,6 @@ if ( jQuery.browser.webkit ) {
|
||||||
jQuery.browser.safari = true;
|
jQuery.browser.safari = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( indexOf ) {
|
|
||||||
jQuery.inArray = function( elem, array ) {
|
|
||||||
return indexOf.call( array, elem );
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
// IE doesn't match non-breaking spaces with \s
|
// IE doesn't match non-breaking spaces with \s
|
||||||
if ( rnotwhite.test( "\xA0" ) ) {
|
if ( rnotwhite.test( "\xA0" ) ) {
|
||||||
trimLeft = /^[\s\xA0]+/;
|
trimLeft = /^[\s\xA0]+/;
|
||||||
|
|
15
src/css.js
15
src/css.js
|
@ -7,6 +7,8 @@ var ralpha = /alpha\([^)]*\)/i,
|
||||||
rupper = /([A-Z]|^ms)/g,
|
rupper = /([A-Z]|^ms)/g,
|
||||||
rnumpx = /^-?\d+(?:px)?$/i,
|
rnumpx = /^-?\d+(?:px)?$/i,
|
||||||
rnum = /^-?\d/,
|
rnum = /^-?\d/,
|
||||||
|
rrelNum = /^[+\-]=/,
|
||||||
|
rrelNumFilter = /[^+\-\.\de]+/g,
|
||||||
|
|
||||||
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
|
cssShow = { position: "absolute", visibility: "hidden", display: "block" },
|
||||||
cssWidth = [ "Left", "Right" ],
|
cssWidth = [ "Left", "Right" ],
|
||||||
|
@ -75,20 +77,27 @@ jQuery.extend({
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure that we're working with the right name
|
// Make sure that we're working with the right name
|
||||||
var ret, origName = jQuery.camelCase( name ),
|
var ret, type, origName = jQuery.camelCase( name ),
|
||||||
style = elem.style, hooks = jQuery.cssHooks[ origName ];
|
style = elem.style, hooks = jQuery.cssHooks[ origName ];
|
||||||
|
|
||||||
name = jQuery.cssProps[ origName ] || origName;
|
name = jQuery.cssProps[ origName ] || origName;
|
||||||
|
|
||||||
// Check if we're setting a value
|
// Check if we're setting a value
|
||||||
if ( value !== undefined ) {
|
if ( value !== undefined ) {
|
||||||
|
type = typeof value;
|
||||||
|
|
||||||
// Make sure that NaN and null values aren't set. See: #7116
|
// Make sure that NaN and null values aren't set. See: #7116
|
||||||
if ( typeof value === "number" && isNaN( value ) || value == null ) {
|
if ( type === "number" && isNaN( value ) || value == null ) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// convert relative number strings (+= or -=) to relative numbers. #7345
|
||||||
|
if ( type === "string" && rrelNum.test( value ) ) {
|
||||||
|
value = +value.replace( rrelNumFilter, '' ) + parseFloat( jQuery.css( elem, name ) );
|
||||||
|
}
|
||||||
|
|
||||||
// If a number was passed in, add 'px' to the (except for certain CSS properties)
|
// If a number was passed in, add 'px' to the (except for certain CSS properties)
|
||||||
if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) {
|
if ( type === "number" && !jQuery.cssNumber[ origName ] ) {
|
||||||
value += "px";
|
value += "px";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
src/data.js
10
src/data.js
|
@ -1,6 +1,7 @@
|
||||||
(function( jQuery ) {
|
(function( jQuery ) {
|
||||||
|
|
||||||
var rbrace = /^(?:\{.*\}|\[.*\])$/;
|
var rbrace = /^(?:\{.*\}|\[.*\])$/,
|
||||||
|
rmultiDash = /([a-z])([A-Z])/g;
|
||||||
|
|
||||||
jQuery.extend({
|
jQuery.extend({
|
||||||
cache: {},
|
cache: {},
|
||||||
|
@ -228,7 +229,8 @@ jQuery.fn.extend({
|
||||||
name = attr[i].name;
|
name = attr[i].name;
|
||||||
|
|
||||||
if ( name.indexOf( "data-" ) === 0 ) {
|
if ( name.indexOf( "data-" ) === 0 ) {
|
||||||
name = name.substr( 5 );
|
name = jQuery.camelCase( name.substring(5) );
|
||||||
|
|
||||||
dataAttr( this[0], name, data[ name ] );
|
dataAttr( this[0], name, data[ name ] );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -282,7 +284,9 @@ function dataAttr( elem, key, data ) {
|
||||||
// If nothing was found internally, try to fetch any
|
// If nothing was found internally, try to fetch any
|
||||||
// data from the HTML5 data-* attribute
|
// data from the HTML5 data-* attribute
|
||||||
if ( data === undefined && elem.nodeType === 1 ) {
|
if ( data === undefined && elem.nodeType === 1 ) {
|
||||||
data = elem.getAttribute( "data-" + key );
|
name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase();
|
||||||
|
|
||||||
|
data = elem.getAttribute( name );
|
||||||
|
|
||||||
if ( typeof data === "string" ) {
|
if ( typeof data === "string" ) {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
(function( jQuery ) {
|
(function( jQuery ) {
|
||||||
|
|
||||||
var // Promise methods
|
var // Promise methods
|
||||||
promiseMethods = "then done fail isResolved isRejected promise".split( " " ),
|
promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ),
|
||||||
// Static reference to slice
|
// Static reference to slice
|
||||||
sliceDeferred = [].slice;
|
sliceDeferred = [].slice;
|
||||||
|
|
||||||
|
@ -100,10 +100,37 @@ jQuery.extend({
|
||||||
deferred.done( doneCallbacks ).fail( failCallbacks );
|
deferred.done( doneCallbacks ).fail( failCallbacks );
|
||||||
return this;
|
return this;
|
||||||
},
|
},
|
||||||
|
always: function() {
|
||||||
|
return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments );
|
||||||
|
},
|
||||||
fail: failDeferred.done,
|
fail: failDeferred.done,
|
||||||
rejectWith: failDeferred.resolveWith,
|
rejectWith: failDeferred.resolveWith,
|
||||||
reject: failDeferred.resolve,
|
reject: failDeferred.resolve,
|
||||||
isRejected: failDeferred.isResolved,
|
isRejected: failDeferred.isResolved,
|
||||||
|
pipe: 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
|
// Get a promise for this deferred
|
||||||
// If obj is provided, the promise aspect is added to the object
|
// If obj is provided, the promise aspect is added to the object
|
||||||
promise: function( obj ) {
|
promise: function( obj ) {
|
||||||
|
|
17
src/effects.js
vendored
17
src/effects.js
vendored
|
@ -11,7 +11,17 @@ var elemdisplay = {},
|
||||||
[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
|
[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
|
||||||
// opacity animations
|
// opacity animations
|
||||||
[ "opacity" ]
|
[ "opacity" ]
|
||||||
];
|
],
|
||||||
|
fxNow;
|
||||||
|
|
||||||
|
function clearFxNow() {
|
||||||
|
fxNow = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function createFxNow() {
|
||||||
|
setTimeout( clearFxNow, 0 );
|
||||||
|
return ( fxNow = jQuery.now() );
|
||||||
|
}
|
||||||
|
|
||||||
jQuery.fn.extend({
|
jQuery.fn.extend({
|
||||||
show: function( speed, easing, callback ) {
|
show: function( speed, easing, callback ) {
|
||||||
|
@ -349,7 +359,7 @@ jQuery.fx.prototype = {
|
||||||
var self = this,
|
var self = this,
|
||||||
fx = jQuery.fx;
|
fx = jQuery.fx;
|
||||||
|
|
||||||
this.startTime = jQuery.now();
|
this.startTime = fxNow || createFxNow();
|
||||||
this.start = from;
|
this.start = from;
|
||||||
this.end = to;
|
this.end = to;
|
||||||
this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
|
this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" );
|
||||||
|
@ -394,7 +404,8 @@ jQuery.fx.prototype = {
|
||||||
|
|
||||||
// Each step of an animation
|
// Each step of an animation
|
||||||
step: function( gotoEnd ) {
|
step: function( gotoEnd ) {
|
||||||
var t = jQuery.now(), done = true;
|
var t = fxNow || createFxNow(),
|
||||||
|
done = true;
|
||||||
|
|
||||||
if ( gotoEnd || t >= this.options.duration + this.startTime ) {
|
if ( gotoEnd || t >= this.options.duration + this.startTime ) {
|
||||||
this.now = this.end;
|
this.now = this.end;
|
||||||
|
|
144
src/event.js
144
src/event.js
|
@ -71,8 +71,8 @@ jQuery.event = {
|
||||||
|
|
||||||
if ( !eventHandle ) {
|
if ( !eventHandle ) {
|
||||||
elemData.handle = eventHandle = function( e ) {
|
elemData.handle = eventHandle = function( e ) {
|
||||||
// Handle the second event of a trigger and when
|
// Discard the second event of a jQuery.event.trigger() and
|
||||||
// an event is called after a page has unloaded
|
// when an event is called after a page has unloaded
|
||||||
return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
|
return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ?
|
||||||
jQuery.event.handle.apply( eventHandle.elem, arguments ) :
|
jQuery.event.handle.apply( eventHandle.elem, arguments ) :
|
||||||
undefined;
|
undefined;
|
||||||
|
@ -143,7 +143,7 @@ jQuery.event = {
|
||||||
// Add the function to the element's handler list
|
// Add the function to the element's handler list
|
||||||
handlers.push( handleObj );
|
handlers.push( handleObj );
|
||||||
|
|
||||||
// Keep track of which events have been used, for global triggering
|
// Keep track of which events have been used, for event optimization
|
||||||
jQuery.event.global[ type ] = true;
|
jQuery.event.global[ type ] = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -277,13 +277,11 @@ jQuery.event = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// bubbling is internal
|
trigger: function( event, data, elem ) {
|
||||||
trigger: function( event, data, elem /*, bubbling */ ) {
|
|
||||||
// Event object or event type
|
// Event object or event type
|
||||||
var type = event.type || event,
|
var type = event.type || event,
|
||||||
bubbling = arguments[3];
|
namespaces = [];
|
||||||
|
|
||||||
if ( !bubbling ) {
|
|
||||||
event = typeof event === "object" ?
|
event = typeof event === "object" ?
|
||||||
// jQuery.Event object
|
// jQuery.Event object
|
||||||
event[ jQuery.expando ] ? event :
|
event[ jQuery.expando ] ? event :
|
||||||
|
@ -293,16 +291,25 @@ jQuery.event = {
|
||||||
jQuery.Event(type);
|
jQuery.Event(type);
|
||||||
|
|
||||||
if ( type.indexOf("!") >= 0 ) {
|
if ( type.indexOf("!") >= 0 ) {
|
||||||
|
// Exclusive events trigger only for the bare event type (no namespaces)
|
||||||
event.type = type = type.slice(0, -1);
|
event.type = type = type.slice(0, -1);
|
||||||
event.exclusive = true;
|
event.exclusive = true;
|
||||||
}
|
}
|
||||||
|
if ( type.indexOf(".") >= 0 ) {
|
||||||
|
// Namespaced trigger; create a regexp to match event type in handle()
|
||||||
|
namespaces = type.split(".");
|
||||||
|
event.type = type = namespaces.shift();
|
||||||
|
namespaces.sort();
|
||||||
|
}
|
||||||
|
event.namespace = namespaces.join(".");
|
||||||
|
event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)");
|
||||||
|
|
||||||
// Handle a global trigger
|
// Handle a global trigger
|
||||||
if ( !elem ) {
|
if ( !elem ) {
|
||||||
// Don't bubble custom events when global (to avoid too much overhead)
|
// Don't bubble custom events when global (to avoid too much overhead)
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
|
|
||||||
// Only trigger if we've ever bound an event for it
|
// Save some time, only trigger if we've ever bound an event for this type
|
||||||
if ( jQuery.event.global[ type ] ) {
|
if ( jQuery.event.global[ type ] ) {
|
||||||
// XXX This code smells terrible. event.js should not be directly
|
// XXX This code smells terrible. event.js should not be directly
|
||||||
// inspecting the data cache
|
// inspecting the data cache
|
||||||
|
@ -317,78 +324,72 @@ jQuery.event = {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle triggering a single element
|
// Don't do events on text and comment nodes
|
||||||
|
if ( elem.nodeType === 3 || elem.nodeType === 8 ) {
|
||||||
// don't do events on text and comment nodes
|
return;
|
||||||
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) {
|
|
||||||
return undefined;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean up in case it is reused
|
// Clean up the event in case it is being reused
|
||||||
event.result = undefined;
|
event.result = undefined;
|
||||||
event.target = elem;
|
event.target = elem;
|
||||||
|
|
||||||
// Clone the incoming data, if any
|
// Clone any incoming data and prepend the event, creating the handler arg list
|
||||||
data = jQuery.makeArray( data );
|
data = jQuery.makeArray( data );
|
||||||
data.unshift( event );
|
data.unshift( event );
|
||||||
}
|
|
||||||
|
|
||||||
event.currentTarget = elem;
|
var cur = elem,
|
||||||
|
// IE doesn't like method names with a colon (#3533, #8272)
|
||||||
|
ontype = type.indexOf(":") < 0? "on" + type : "";
|
||||||
|
|
||||||
// Trigger the event, it is assumed that "handle" is a function
|
// Fire event on the current element, then bubble up the DOM tree
|
||||||
var handle = jQuery._data( elem, "handle" );
|
do {
|
||||||
|
var handle = jQuery._data( cur, "handle" );
|
||||||
|
|
||||||
|
event.currentTarget = cur;
|
||||||
if ( handle ) {
|
if ( handle ) {
|
||||||
handle.apply( elem, data );
|
handle.apply( cur, data );
|
||||||
}
|
}
|
||||||
|
|
||||||
var parent = elem.parentNode || elem.ownerDocument;
|
|
||||||
|
|
||||||
// Trigger an inline bound script
|
// Trigger an inline bound script
|
||||||
try {
|
if ( ontype &&jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
|
||||||
if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) {
|
|
||||||
if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) {
|
|
||||||
event.result = false;
|
event.result = false;
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// prevent IE from throwing an error for some elements with some event types, see #3533
|
// Bubble up to document, then to window
|
||||||
} catch (inlineError) {}
|
cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
|
||||||
|
} while ( cur && !event.isPropagationStopped() );
|
||||||
|
|
||||||
if ( !event.isPropagationStopped() && parent ) {
|
// If nobody prevented the default action, do it now
|
||||||
jQuery.event.trigger( event, data, parent, true );
|
if ( !event.isDefaultPrevented() ) {
|
||||||
|
|
||||||
} else if ( !event.isDefaultPrevented() ) {
|
|
||||||
var old,
|
var old,
|
||||||
target = event.target,
|
special = jQuery.event.special[ type ] || {};
|
||||||
targetType = type.replace( rnamespaces, "" ),
|
|
||||||
isClick = jQuery.nodeName( target, "a" ) && targetType === "click",
|
|
||||||
special = jQuery.event.special[ targetType ] || {};
|
|
||||||
|
|
||||||
if ( (!special._default || special._default.call( elem, event ) === false) &&
|
if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) &&
|
||||||
!isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) {
|
!(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) {
|
||||||
|
|
||||||
|
// Call a native DOM method on the target with the same name name as the event.
|
||||||
|
// Can't use an .isFunction)() check here because IE6/7 fails that test.
|
||||||
|
// IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
|
||||||
try {
|
try {
|
||||||
if ( target[ targetType ] ) {
|
if ( ontype && elem[ type ] ) {
|
||||||
// Make sure that we don't accidentally re-trigger the onFOO events
|
// Don't re-trigger an onFOO event when we call its FOO() method
|
||||||
old = target[ "on" + targetType ];
|
old = elem[ ontype ];
|
||||||
|
|
||||||
if ( old ) {
|
if ( old ) {
|
||||||
target[ "on" + targetType ] = null;
|
elem[ ontype ] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
jQuery.event.triggered = event.type;
|
jQuery.event.triggered = type;
|
||||||
target[ targetType ]();
|
elem[ type ]();
|
||||||
}
|
}
|
||||||
|
} catch ( ieError ) {}
|
||||||
// prevent IE from throwing an error for some elements with some event types, see #3533
|
|
||||||
} catch (triggerError) {}
|
|
||||||
|
|
||||||
if ( old ) {
|
if ( old ) {
|
||||||
target[ "on" + targetType ] = old;
|
elem[ ontype ] = old;
|
||||||
}
|
}
|
||||||
|
|
||||||
jQuery.event.triggered = undefined;
|
jQuery.event.triggered = undefined;
|
||||||
|
@ -397,38 +398,22 @@ jQuery.event = {
|
||||||
},
|
},
|
||||||
|
|
||||||
handle: function( event ) {
|
handle: function( event ) {
|
||||||
var all, handlers, namespaces, namespace_re, events,
|
event = jQuery.event.fix( event || window.event );
|
||||||
namespace_sort = [],
|
// Snapshot the handlers list since a called handler may add/remove events.
|
||||||
|
var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0),
|
||||||
|
run_all = !event.exclusive && !event.namespace,
|
||||||
args = jQuery.makeArray( arguments );
|
args = jQuery.makeArray( arguments );
|
||||||
|
|
||||||
event = args[0] = jQuery.event.fix( event || window.event );
|
// Use the fix-ed Event rather than the (read-only) native event
|
||||||
|
args[0] = event;
|
||||||
event.currentTarget = this;
|
event.currentTarget = this;
|
||||||
|
|
||||||
// Namespaced event handlers
|
|
||||||
all = event.type.indexOf(".") < 0 && !event.exclusive;
|
|
||||||
|
|
||||||
if ( !all ) {
|
|
||||||
namespaces = event.type.split(".");
|
|
||||||
event.type = namespaces.shift();
|
|
||||||
namespace_sort = namespaces.slice(0).sort();
|
|
||||||
namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)");
|
|
||||||
}
|
|
||||||
|
|
||||||
event.namespace = event.namespace || namespace_sort.join(".");
|
|
||||||
|
|
||||||
events = jQuery._data(this, "events");
|
|
||||||
|
|
||||||
handlers = (events || {})[ event.type ];
|
|
||||||
|
|
||||||
if ( events && handlers ) {
|
|
||||||
// Clone the handlers to prevent manipulation
|
|
||||||
handlers = handlers.slice(0);
|
|
||||||
|
|
||||||
for ( var j = 0, l = handlers.length; j < l; j++ ) {
|
for ( var j = 0, l = handlers.length; j < l; j++ ) {
|
||||||
var handleObj = handlers[ j ];
|
var handleObj = handlers[ j ];
|
||||||
|
|
||||||
// Filter the functions by class
|
// Triggered event must 1) be non-exclusive and have no namespace, or
|
||||||
if ( all || namespace_re.test( handleObj.namespace ) ) {
|
// 2) have namespace(s) a subset or equal to those in the bound event.
|
||||||
|
if ( run_all || event.namespace_re.test( handleObj.namespace ) ) {
|
||||||
// Pass in a reference to the handler function itself
|
// Pass in a reference to the handler function itself
|
||||||
// So that we can later remove it
|
// So that we can later remove it
|
||||||
event.handler = handleObj.handler;
|
event.handler = handleObj.handler;
|
||||||
|
@ -450,8 +435,6 @@ jQuery.event = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return event.result;
|
return event.result;
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -490,8 +473,9 @@ jQuery.event = {
|
||||||
|
|
||||||
// Calculate pageX/Y if missing and clientX/Y available
|
// Calculate pageX/Y if missing and clientX/Y available
|
||||||
if ( event.pageX == null && event.clientX != null ) {
|
if ( event.pageX == null && event.clientX != null ) {
|
||||||
var doc = document.documentElement,
|
var eventDocument = event.target.ownerDocument || document,
|
||||||
body = document.body;
|
doc = eventDocument.documentElement,
|
||||||
|
body = eventDocument.body;
|
||||||
|
|
||||||
event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
|
event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0);
|
||||||
event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
|
event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0);
|
||||||
|
@ -866,7 +850,7 @@ function trigger( type, elem, args ) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create "bubbling" focus and blur events
|
// Create "bubbling" focus and blur events
|
||||||
if ( document.addEventListener ) {
|
if ( !jQuery.support.focusinBubbles ) {
|
||||||
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
|
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
|
||||||
|
|
||||||
// Attach a single capturing handler while someone wants focusin/focusout
|
// Attach a single capturing handler while someone wants focusin/focusout
|
||||||
|
@ -1027,8 +1011,8 @@ jQuery.each(["live", "die"], function( i, name ) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( jQuery.isFunction( data ) ) {
|
if ( data === false || jQuery.isFunction( data ) ) {
|
||||||
fn = data;
|
fn = data || returnFalse;
|
||||||
data = undefined;
|
data = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
45
src/queue.js
45
src/queue.js
|
@ -28,7 +28,8 @@ jQuery.extend({
|
||||||
type = type || "fx";
|
type = type || "fx";
|
||||||
|
|
||||||
var queue = jQuery.queue( elem, type ),
|
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 the fx queue is dequeued, always remove the progress sentinel
|
||||||
if ( fn === "inprogress" ) {
|
if ( fn === "inprogress" ) {
|
||||||
|
@ -49,6 +50,17 @@ jQuery.extend({
|
||||||
|
|
||||||
if ( !queue.length ) {
|
if ( !queue.length ) {
|
||||||
jQuery.removeData( elem, type + "queue", true );
|
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 ) {
|
clearQueue: function( type ) {
|
||||||
return this.queue( type || "fx", [] );
|
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();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit f12b9309269ba7e705a99efe099f86ed1fe98d58
|
Subproject commit 80f2b81d1fbc13d62afb91cb87e1452fbbec1ef4
|
189
src/support.js
189
src/support.js
|
@ -1,29 +1,42 @@
|
||||||
(function( jQuery ) {
|
(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");
|
// Preliminary tests
|
||||||
|
div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
|
||||||
|
|
||||||
div.style.display = "none";
|
all = div.getElementsByTagName( "*" );
|
||||||
div.setAttribute("className", "t");
|
a = div.getElementsByTagName( "a" )[ 0 ];
|
||||||
div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;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];
|
|
||||||
|
|
||||||
// Can't get basic test support
|
// Can't get basic test support
|
||||||
if ( !all || !all.length || !a ) {
|
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
|
// 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
|
// Make sure that tbody elements aren't automatically inserted
|
||||||
// IE will insert them into empty tables
|
// IE will insert them into empty tables
|
||||||
|
@ -34,12 +47,12 @@
|
||||||
htmlSerialize: !!div.getElementsByTagName( "link" ).length,
|
htmlSerialize: !!div.getElementsByTagName( "link" ).length,
|
||||||
|
|
||||||
// Get the style information from getAttribute
|
// Get the style information from getAttribute
|
||||||
// (IE uses .cssText instead, and capitalizes all property names)
|
// (IE uses .cssText instead)
|
||||||
style: /top/.test( a.getAttribute("style") ),
|
style: /red/.test( a.getAttribute("style") ),
|
||||||
|
|
||||||
// Make sure that URLs aren't manipulated
|
// Make sure that URLs aren't manipulated
|
||||||
// (IE normalizes it by default)
|
// (IE normalizes it by default)
|
||||||
hrefNormalized: a.getAttribute("href") === "/a",
|
hrefNormalized: ( a.getAttribute( "href" ) === "/a" ),
|
||||||
|
|
||||||
// Make sure that element opacity exists
|
// Make sure that element opacity exists
|
||||||
// (IE uses filter instead)
|
// (IE uses filter instead)
|
||||||
|
@ -53,7 +66,7 @@
|
||||||
// Make sure that if no value is specified for a checkbox
|
// Make sure that if no value is specified for a checkbox
|
||||||
// that it defaults to "on".
|
// that it defaults to "on".
|
||||||
// (WebKit defaults to "" instead)
|
// (WebKit defaults to "" instead)
|
||||||
checkOn: input.value === "on",
|
checkOn: ( input.value === "on" ),
|
||||||
|
|
||||||
// Make sure that a selected-by-default option has a working selected property.
|
// Make sure that a selected-by-default option has a working selected property.
|
||||||
// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
|
// (WebKit defaults to false instead of true, IE too, if it's in an optgroup)
|
||||||
|
@ -63,97 +76,72 @@
|
||||||
getSetAttribute: div.className !== "t",
|
getSetAttribute: div.className !== "t",
|
||||||
|
|
||||||
// Will be defined later
|
// Will be defined later
|
||||||
|
submitBubbles: true,
|
||||||
|
changeBubbles: true,
|
||||||
|
focusinBubbles: false,
|
||||||
deleteExpando: true,
|
deleteExpando: true,
|
||||||
optDisabled: false,
|
|
||||||
checkClone: false,
|
|
||||||
noCloneEvent: true,
|
noCloneEvent: true,
|
||||||
noCloneChecked: true,
|
|
||||||
boxModel: null,
|
|
||||||
inlineBlockNeedsLayout: false,
|
inlineBlockNeedsLayout: false,
|
||||||
shrinkWrapBlocks: false,
|
shrinkWrapBlocks: false,
|
||||||
reliableHiddenOffsets: true,
|
|
||||||
reliableMarginRight: true
|
reliableMarginRight: true
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Make sure checked status is properly cloned
|
||||||
input.checked = true;
|
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
|
// 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;
|
select.disabled = true;
|
||||||
jQuery.support.optDisabled = !opt.disabled;
|
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;
|
|
||||||
};
|
|
||||||
|
|
||||||
// Test to see if it's possible to delete an expando from an element
|
// Test to see if it's possible to delete an expando from an element
|
||||||
// Fails in Internet Explorer
|
// Fails in Internet Explorer
|
||||||
try {
|
try {
|
||||||
delete div.test;
|
delete div.test;
|
||||||
|
|
||||||
} catch( e ) {
|
} catch( e ) {
|
||||||
jQuery.support.deleteExpando = false;
|
support.deleteExpando = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( !div.addEventListener && div.attachEvent && div.fireEvent ) {
|
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
|
// Cloning a node shouldn't copy over any
|
||||||
// bound event handlers (IE does this)
|
// bound event handlers (IE does this)
|
||||||
jQuery.support.noCloneEvent = false;
|
support.noCloneEvent = false;
|
||||||
div.detachEvent( "onclick", click );
|
div.detachEvent( "onclick", click );
|
||||||
});
|
});
|
||||||
div.cloneNode( true ).fireEvent( "onclick" );
|
div.cloneNode( true ).fireEvent( "onclick" );
|
||||||
}
|
}
|
||||||
|
|
||||||
div = document.createElement("div");
|
|
||||||
div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
|
div.innerHTML = "<input type='radio' name='radiotest' checked='checked'/>";
|
||||||
|
|
||||||
var fragment = document.createDocumentFragment();
|
fragment = document.createDocumentFragment();
|
||||||
fragment.appendChild( div.firstChild );
|
fragment.appendChild( div.firstChild );
|
||||||
|
|
||||||
// WebKit doesn't clone checked state correctly in fragments
|
// 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
|
// 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];
|
|
||||||
|
|
||||||
// Frameset documents with no body should not run this code
|
|
||||||
if ( !body ) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
div.style.width = div.style.paddingLeft = "1px";
|
div.style.width = div.style.paddingLeft = "1px";
|
||||||
|
|
||||||
|
// 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 );
|
body.appendChild( div );
|
||||||
jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2;
|
document.documentElement.appendChild( body );
|
||||||
|
|
||||||
|
support.boxModel = div.offsetWidth === 2;
|
||||||
|
|
||||||
if ( "zoom" in div.style ) {
|
if ( "zoom" in div.style ) {
|
||||||
// Check if natively block-level elements act like inline-block
|
// Check if natively block-level elements act like inline-block
|
||||||
|
@ -162,17 +150,17 @@
|
||||||
// (IE < 8 does this)
|
// (IE < 8 does this)
|
||||||
div.style.display = "inline";
|
div.style.display = "inline";
|
||||||
div.style.zoom = 1;
|
div.style.zoom = 1;
|
||||||
jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2;
|
support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 );
|
||||||
|
|
||||||
// Check if elements with layout shrink-wrap their children
|
// Check if elements with layout shrink-wrap their children
|
||||||
// (IE 6 does this)
|
// (IE 6 does this)
|
||||||
div.style.display = "";
|
div.style.display = "";
|
||||||
div.innerHTML = "<div style='width:4px;'></div>";
|
div.innerHTML = "<div style='width:4px;'></div>";
|
||||||
jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2;
|
support.shrinkWrapBlocks = ( div.offsetWidth !== 2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
|
div.innerHTML = "<table><tr><td style='padding:0;border:0;display:none'></td><td>t</td></tr></table>";
|
||||||
var tds = div.getElementsByTagName("td");
|
tds = div.getElementsByTagName( "td" );
|
||||||
|
|
||||||
// Check if table cells still have offsetWidth/Height when they are set
|
// 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
|
// to display:none and there are still other visible table cells in a
|
||||||
|
@ -181,14 +169,14 @@
|
||||||
// display:none (it is still safe to use offsets if a parent element is
|
// 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).
|
// hidden; don safety goggles and see bug #4512 for more information).
|
||||||
// (only IE 8 fails this test)
|
// (only IE 8 fails this test)
|
||||||
jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0;
|
isSupported = ( tds[ 0 ].offsetHeight === 0 );
|
||||||
|
|
||||||
tds[ 0 ].style.display = "";
|
tds[ 0 ].style.display = "";
|
||||||
tds[ 1 ].style.display = "none";
|
tds[ 1 ].style.display = "none";
|
||||||
|
|
||||||
// Check if empty table cells still have offsetWidth/Height
|
// Check if empty table cells still have offsetWidth/Height
|
||||||
// (IE < 8 fail this test)
|
// (IE < 8 fail this test)
|
||||||
jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0;
|
support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 );
|
||||||
div.innerHTML = "";
|
div.innerHTML = "";
|
||||||
|
|
||||||
// Check if div with explicit width and no margin-right incorrectly
|
// Check if div with explicit width and no margin-right incorrectly
|
||||||
|
@ -199,39 +187,42 @@
|
||||||
if ( document.defaultView && document.defaultView.getComputedStyle ) {
|
if ( document.defaultView && document.defaultView.getComputedStyle ) {
|
||||||
div.style.width = "1px";
|
div.style.width = "1px";
|
||||||
div.style.marginRight = "0";
|
div.style.marginRight = "0";
|
||||||
jQuery.support.reliableMarginRight = ( parseInt(document.defaultView.getComputedStyle(div, null).marginRight, 10) || 0 ) === 0;
|
support.reliableMarginRight =
|
||||||
|
( parseInt( document.defaultView.getComputedStyle(div).marginRight, 10 ) || 0 ) === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
body.removeChild( div ).style.display = "none";
|
// Remove the body element we added
|
||||||
div = tds = null;
|
document.documentElement.removeChild( body );
|
||||||
});
|
|
||||||
|
|
||||||
// Technique from Juriy Zaytsev
|
// Technique from Juriy Zaytsev
|
||||||
// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
|
// 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
|
// We only care about the case where non-standard event systems
|
||||||
// are used, namely in IE. Short-circuiting here helps us to
|
// are used, namely in IE. Short-circuiting here helps us to
|
||||||
// avoid an eval call (in setAttribute) which can cause CSP
|
// avoid an eval call (in setAttribute) which can cause CSP
|
||||||
// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
|
// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
|
||||||
if ( !el.attachEvent ) {
|
if ( div.attachEvent ) {
|
||||||
return true;
|
for( i in {
|
||||||
}
|
submit: 1,
|
||||||
|
change: 1,
|
||||||
var isSupported = (eventName in el);
|
focusin: 1
|
||||||
|
} ) {
|
||||||
|
eventName = "on" + i;
|
||||||
|
isSupported = ( eventName in div );
|
||||||
if ( !isSupported ) {
|
if ( !isSupported ) {
|
||||||
el.setAttribute(eventName, "return;");
|
div.setAttribute( eventName, "return;" );
|
||||||
isSupported = typeof el[eventName] === "function";
|
isSupported = ( typeof div[ eventName ] === "function" );
|
||||||
|
}
|
||||||
|
support[ i + "Bubbles" ] = isSupported;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return isSupported;
|
|
||||||
};
|
|
||||||
|
|
||||||
jQuery.support.submitBubbles = eventSupported("submit");
|
|
||||||
jQuery.support.changeBubbles = eventSupported("change");
|
|
||||||
|
|
||||||
// release memory in IE
|
// 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 );
|
})( jQuery );
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
// Simple script loader that uses jQuery.readyWait
|
// Simple script loader that uses jQuery.readyWait via jQuery.holdReady()
|
||||||
|
|
||||||
//Hold on jQuery!
|
//Hold on jQuery!
|
||||||
jQuery.readyWait++;
|
jQuery.holdReady(true);
|
||||||
|
|
||||||
var readyRegExp = /^(complete|loaded)$/;
|
var readyRegExp = /^(complete|loaded)$/;
|
||||||
|
|
||||||
function assetLoaded( evt ){
|
function assetLoaded( evt ){
|
||||||
var node = evt.currentTarget || evt.srcElement;
|
var node = evt.currentTarget || evt.srcElement;
|
||||||
if ( evt.type === "load" || readyRegExp.test(node.readyState) ) {
|
if ( evt.type === "load" || readyRegExp.test(node.readyState) ) {
|
||||||
jQuery.ready(true);
|
jQuery.holdReady(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<!--
|
<!--
|
||||||
Test for jQuery.readyWait. Needs to be a
|
Test for jQuery.holdReady. Needs to be a
|
||||||
standalone test since it deals with DOM
|
standalone test since it deals with DOM
|
||||||
ready.
|
ready.
|
||||||
-->
|
-->
|
||||||
<head>
|
<head>
|
||||||
<title>
|
<title>
|
||||||
jQuery.readyWait Test
|
jQuery.holdReady Test
|
||||||
</title>
|
</title>
|
||||||
<style>
|
<style>
|
||||||
div { margin-top: 10px; }
|
div { margin-top: 10px; }
|
||||||
|
@ -52,15 +52,17 @@
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<h1>
|
<h1>
|
||||||
jQuery.readyWait Test
|
jQuery.holdReady Test
|
||||||
</h1>
|
</h1>
|
||||||
<p>
|
<p>
|
||||||
This is a test page for jQuery.readyWait, that was
|
This is a test page for jQuery.readyWait and jQuery.holdReady,
|
||||||
added due to this ticket
|
see
|
||||||
<a href="http://bugs.jquery.com/ticket/6781">#6781</a>.
|
<a href="http://bugs.jquery.com/ticket/6781">#6781</a>
|
||||||
|
and
|
||||||
|
<a href="http://bugs.jquery.com/ticket/8803">#8803</a>.
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Test for jQuery.readyWait, which can be used
|
Test for jQuery.holdReady, which can be used
|
||||||
by plugins and other scripts to indicate something
|
by plugins and other scripts to indicate something
|
||||||
important to the page is still loading and needs
|
important to the page is still loading and needs
|
||||||
to block the DOM ready callbacks that are registered
|
to block the DOM ready callbacks that are registered
|
||||||
|
@ -68,7 +70,7 @@
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
Script loaders are the most likely kind of script
|
Script loaders are the most likely kind of script
|
||||||
to use jQuery.readyWait, but it could be used by
|
to use jQuery.holdReady, but it could be used by
|
||||||
other things like a script that loads a CSS file
|
other things like a script that loads a CSS file
|
||||||
and wants to pause the DOM ready callbacks.
|
and wants to pause the DOM ready callbacks.
|
||||||
</p>
|
</p>
|
||||||
|
|
|
@ -1600,7 +1600,7 @@ test("jQuery.ajax() - malformed JSON", function() {
|
||||||
},
|
},
|
||||||
error: function(xhr, msg, detailedMsg) {
|
error: function(xhr, msg, detailedMsg) {
|
||||||
equals( "parsererror", msg, "A parse error occurred." );
|
equals( "parsererror", msg, "A parse error occurred." );
|
||||||
ok( /^Invalid JSON/.test(detailedMsg), "Detailed parsererror message provided" );
|
ok( /^(Invalid|SyntaxError|exception)/i.test(detailedMsg), "Detailed parsererror message provided" );
|
||||||
start();
|
start();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -12,7 +12,7 @@ test("Basic requirements", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("jQuery()", function() {
|
test("jQuery()", function() {
|
||||||
expect(24);
|
expect(25);
|
||||||
|
|
||||||
// Basic constructor's behavior
|
// Basic constructor's behavior
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ test("jQuery()", function() {
|
||||||
equals( jQuery(undefined).length, 0, "jQuery(undefined) === jQuery([])" );
|
equals( jQuery(undefined).length, 0, "jQuery(undefined) === jQuery([])" );
|
||||||
equals( jQuery(null).length, 0, "jQuery(null) === jQuery([])" );
|
equals( jQuery(null).length, 0, "jQuery(null) === jQuery([])" );
|
||||||
equals( jQuery("").length, 0, "jQuery('') === jQuery([])" );
|
equals( jQuery("").length, 0, "jQuery('') === jQuery([])" );
|
||||||
|
equals( jQuery("#").length, 0, "jQuery('#') === jQuery([])" );
|
||||||
|
|
||||||
var obj = jQuery("div");
|
var obj = jQuery("div");
|
||||||
equals( jQuery(obj).selector, "div", "jQuery(jQueryObj) == jQueryObj" );
|
equals( jQuery(obj).selector, "div", "jQuery(jQueryObj) == jQueryObj" );
|
||||||
|
@ -171,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 ) {
|
if ( !isLocal ) {
|
||||||
test("browser", function() {
|
test("browser", function() {
|
||||||
stop();
|
stop();
|
||||||
|
@ -468,7 +489,7 @@ test("isWindow", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("jQuery('html')", function() {
|
test("jQuery('html')", function() {
|
||||||
expect(15);
|
expect(18);
|
||||||
|
|
||||||
QUnit.reset();
|
QUnit.reset();
|
||||||
jQuery.foo = false;
|
jQuery.foo = false;
|
||||||
|
@ -500,6 +521,19 @@ test("jQuery('html')", function() {
|
||||||
|
|
||||||
ok( jQuery("<div></div>")[0], "Create a div with closing tag." );
|
ok( jQuery("<div></div>")[0], "Create a div with closing tag." );
|
||||||
ok( jQuery("<table></table>")[0], "Create a table with closing tag." );
|
ok( jQuery("<table></table>")[0], "Create a table with closing tag." );
|
||||||
|
|
||||||
|
// Test very large html string #7990
|
||||||
|
var i;
|
||||||
|
var li = '<li>very large html string</li>';
|
||||||
|
var html = ['<ul>'];
|
||||||
|
for ( i = 0; i < 50000; i += 1 ) {
|
||||||
|
html.push(li);
|
||||||
|
}
|
||||||
|
html.push('</ul>');
|
||||||
|
html = jQuery(html.join(''))[0];
|
||||||
|
equals( html.nodeName.toUpperCase(), 'UL');
|
||||||
|
equals( html.firstChild.nodeName.toUpperCase(), 'LI');
|
||||||
|
equals( html.childNodes.length, 50000 );
|
||||||
});
|
});
|
||||||
|
|
||||||
test("jQuery('html', context)", function() {
|
test("jQuery('html', context)", function() {
|
||||||
|
|
|
@ -105,6 +105,38 @@ test("css(String|Hash)", function() {
|
||||||
equals( child[0].style.fontSize, old, "Make sure font-size isn't changed on null." );
|
equals( child[0].style.fontSize, old, "Make sure font-size isn't changed on null." );
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("css() explicit and relative values", function() {
|
||||||
|
expect(9);
|
||||||
|
var $elem = jQuery('#nothiddendiv');
|
||||||
|
|
||||||
|
$elem.css({ width: 1, height: 1 });
|
||||||
|
equals( $elem.width(), 1, "Initial css set or width/height works (hash)" );
|
||||||
|
|
||||||
|
$elem.css({ width: "+=9" });
|
||||||
|
equals( $elem.width(), 10, "'+=9' on width (hash)" );
|
||||||
|
|
||||||
|
$elem.css({ width: "-=9" });
|
||||||
|
equals( $elem.width(), 1, "'-=9' on width (hash)" );
|
||||||
|
|
||||||
|
$elem.css({ width: "+=9px" });
|
||||||
|
equals( $elem.width(), 10, "'+=9px' on width (hash)" );
|
||||||
|
|
||||||
|
$elem.css({ width: "-=9px" });
|
||||||
|
equals( $elem.width(), 1, "'-=9px' on width (hash)" );
|
||||||
|
|
||||||
|
$elem.css( "width", "+=9" );
|
||||||
|
equals( $elem.width(), 10, "'+=9' on width (params)" );
|
||||||
|
|
||||||
|
$elem.css( "width", "-=9" ) ;
|
||||||
|
equals( $elem.width(), 1, "'-=9' on width (params)" );
|
||||||
|
|
||||||
|
$elem.css( "width", "+=9px" );
|
||||||
|
equals( $elem.width(), 10, "'+=9px' on width (params)" );
|
||||||
|
|
||||||
|
$elem.css( "width", "-=9px" );
|
||||||
|
equals( $elem.width(), 1, "'-=9px' on width (params)" );
|
||||||
|
});
|
||||||
|
|
||||||
test("css(String, Object)", function() {
|
test("css(String, Object)", function() {
|
||||||
expect(22);
|
expect(22);
|
||||||
|
|
||||||
|
|
|
@ -486,3 +486,20 @@ if (window.JSON && window.JSON.stringify) {
|
||||||
equals( JSON.stringify(obj), '{"foo":"bar"}', "Expando is hidden from JSON.stringify" );
|
equals( JSON.stringify(obj), '{"foo":"bar"}', "Expando is hidden from JSON.stringify" );
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
test("jQuery.data should follow html5 specification regarding camel casing", function() {
|
||||||
|
expect(6);
|
||||||
|
|
||||||
|
var div = jQuery("<div id='myObject' data-foo='a' data-foo-bar='b' data-foo-bar-baz='c'></div>")
|
||||||
|
.prependTo("body");
|
||||||
|
|
||||||
|
equals(div.data().foo, "a", "Verify single word data-* key");
|
||||||
|
equals(div.data().fooBar, "b", "Verify multiple word data-* key");
|
||||||
|
equals(div.data().fooBarBaz, "c", "Verify multiple word data-* key");
|
||||||
|
|
||||||
|
equals(div.data("foo"), "a", "Verify single word data-* key");
|
||||||
|
equals(div.data("fooBar"), "b", "Verify multiple word data-* key");
|
||||||
|
equals(div.data("fooBarBaz"), "c", "Verify multiple word data-* key");
|
||||||
|
|
||||||
|
div.remove();
|
||||||
|
});
|
|
@ -1,6 +1,12 @@
|
||||||
module("deferred", { teardown: moduleTeardown });
|
module("deferred", { teardown: moduleTeardown });
|
||||||
|
|
||||||
test("jQuery._Deferred()", function() {
|
jQuery.each( [ "", " - new operator" ], function( _, withNew ) {
|
||||||
|
|
||||||
|
function createDeferred() {
|
||||||
|
return withNew ? new jQuery._Deferred() : jQuery._Deferred();
|
||||||
|
}
|
||||||
|
|
||||||
|
test("jQuery._Deferred" + withNew, function() {
|
||||||
|
|
||||||
expect( 11 );
|
expect( 11 );
|
||||||
|
|
||||||
|
@ -8,7 +14,7 @@ test("jQuery._Deferred()", function() {
|
||||||
object,
|
object,
|
||||||
test;
|
test;
|
||||||
|
|
||||||
deferred = jQuery._Deferred();
|
deferred = createDeferred();
|
||||||
|
|
||||||
test = false;
|
test = false;
|
||||||
|
|
||||||
|
@ -41,7 +47,7 @@ test("jQuery._Deferred()", function() {
|
||||||
|
|
||||||
ok( test , "Test cancel" );
|
ok( test , "Test cancel" );
|
||||||
|
|
||||||
deferred = jQuery._Deferred().resolve();
|
deferred = createDeferred().resolve();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
deferred.done( function() {
|
deferred.done( function() {
|
||||||
|
@ -55,7 +61,7 @@ test("jQuery._Deferred()", function() {
|
||||||
}
|
}
|
||||||
|
|
||||||
test = "";
|
test = "";
|
||||||
deferred = jQuery._Deferred().done( function() {
|
deferred = createDeferred().done( function() {
|
||||||
|
|
||||||
test += "A";
|
test += "A";
|
||||||
|
|
||||||
|
@ -86,68 +92,182 @@ test("jQuery._Deferred()", function() {
|
||||||
|
|
||||||
strictEqual( test , "ABC" , "Test done callbacks order" );
|
strictEqual( test , "ABC" , "Test done callbacks order" );
|
||||||
|
|
||||||
deferred = jQuery._Deferred();
|
deferred = createDeferred();
|
||||||
|
|
||||||
deferred.resolveWith( jQuery , [ document ] ).done( function( doc ) {
|
deferred.resolveWith( jQuery , [ document ] ).done( function( doc ) {
|
||||||
ok( this === jQuery && arguments.length === 1 && doc === document , "Test fire context & args" );
|
ok( this === jQuery && arguments.length === 1 && doc === document , "Test fire context & args" );
|
||||||
});
|
});
|
||||||
|
|
||||||
// #8421
|
// #8421
|
||||||
deferred = jQuery._Deferred();
|
deferred = createDeferred();
|
||||||
deferred.resolveWith().done(function() {
|
deferred.resolveWith().done(function() {
|
||||||
ok( true, "Test resolveWith can be called with no argument" );
|
ok( true, "Test resolveWith can be called with no argument" );
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
} );
|
||||||
|
|
||||||
test("jQuery.Deferred()", function() {
|
jQuery.each( [ "", " - new operator" ], function( _, withNew ) {
|
||||||
|
|
||||||
expect( 10 );
|
function createDeferred( fn ) {
|
||||||
|
return withNew ? new jQuery.Deferred( fn ) : jQuery.Deferred( fn );
|
||||||
|
}
|
||||||
|
|
||||||
jQuery.Deferred( function( defer ) {
|
test("jQuery.Deferred" + withNew, function() {
|
||||||
strictEqual( this , defer , "Defer passed as this & first argument" );
|
|
||||||
|
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" );
|
this.resolve( "done" );
|
||||||
}).then( function( value ) {
|
}).then( function( value ) {
|
||||||
strictEqual( value , "done" , "Passed function executed" );
|
strictEqual( value , "done" , "Passed function executed" );
|
||||||
});
|
});
|
||||||
|
});
|
||||||
jQuery.Deferred().resolve().then( function() {
|
|
||||||
ok( true , "Success on resolve" );
|
|
||||||
}, function() {
|
|
||||||
ok( false , "Error on resolve" );
|
|
||||||
} );
|
} );
|
||||||
|
|
||||||
jQuery.Deferred().reject().then( function() {
|
test( "jQuery.Deferred.pipe - filtering (done)", function() {
|
||||||
ok( false , "Success on reject" );
|
|
||||||
}, function() {
|
expect(3);
|
||||||
ok( true , "Error on reject" );
|
|
||||||
|
var defer = jQuery.Deferred(),
|
||||||
|
piped = defer.pipe(function( a, b ) {
|
||||||
|
return a * b;
|
||||||
|
}),
|
||||||
|
value1,
|
||||||
|
value2,
|
||||||
|
value3;
|
||||||
|
|
||||||
|
piped.done(function( result ) {
|
||||||
|
value3 = result;
|
||||||
});
|
});
|
||||||
|
|
||||||
( new jQuery.Deferred( function( defer ) {
|
defer.done(function( a, b ) {
|
||||||
strictEqual( this , defer , "Defer passed as this & first argument (new)" );
|
value1 = a;
|
||||||
this.resolve( "done" );
|
value2 = b;
|
||||||
}) ).then( function( value ) {
|
|
||||||
strictEqual( value , "done" , "Passed function executed (new)" );
|
|
||||||
});
|
});
|
||||||
|
|
||||||
( new jQuery.Deferred() ).resolve().then( function() {
|
defer.resolve( 2, 3 );
|
||||||
ok( true , "Success on resolve (new)" );
|
|
||||||
}, function() {
|
strictEqual( value1, 2, "first resolve value ok" );
|
||||||
ok( false , "Error on resolve (new)" );
|
strictEqual( value2, 3, "second resolve value ok" );
|
||||||
|
strictEqual( value3, 6, "result of filter ok" );
|
||||||
|
|
||||||
|
jQuery.Deferred().reject().pipe(function() {
|
||||||
|
ok( false, "pipe should not be called on reject" );
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
( new jQuery.Deferred() ).reject().then( function() {
|
test( "jQuery.Deferred.pipe - filtering (fail)", function() {
|
||||||
ok( false , "Success on reject (new)" );
|
|
||||||
}, function() {
|
expect(3);
|
||||||
ok( true , "Error on reject (new)" );
|
|
||||||
|
var defer = jQuery.Deferred(),
|
||||||
|
piped = defer.pipe( null, function( a, b ) {
|
||||||
|
return a * b;
|
||||||
|
} ),
|
||||||
|
value1,
|
||||||
|
value2,
|
||||||
|
value3;
|
||||||
|
|
||||||
|
piped.fail(function( result ) {
|
||||||
|
value3 = result;
|
||||||
});
|
});
|
||||||
|
|
||||||
var tmp = jQuery.Deferred();
|
defer.fail(function( a, b ) {
|
||||||
|
value1 = a;
|
||||||
strictEqual( tmp.promise() , tmp.promise() , "Test deferred always return same promise" );
|
value2 = b;
|
||||||
strictEqual( tmp.promise() , tmp.promise().promise() , "Test deferred's promise always return same promise as deferred" );
|
|
||||||
});
|
});
|
||||||
|
|
||||||
test("jQuery.when()", function() {
|
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().pipe( null, function() {
|
||||||
|
ok( false, "pipe should not be called on resolve" );
|
||||||
|
} );
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "jQuery.Deferred.pipe - deferred (done)", function() {
|
||||||
|
|
||||||
|
expect(3);
|
||||||
|
|
||||||
|
var defer = jQuery.Deferred(),
|
||||||
|
piped = defer.pipe(function( a, b ) {
|
||||||
|
return jQuery.Deferred(function( defer ) {
|
||||||
|
defer.reject( a * b );
|
||||||
|
});
|
||||||
|
}),
|
||||||
|
value1,
|
||||||
|
value2,
|
||||||
|
value3;
|
||||||
|
|
||||||
|
piped.fail(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" );
|
||||||
|
});
|
||||||
|
|
||||||
|
test( "jQuery.Deferred.pipe - deferred (fail)", function() {
|
||||||
|
|
||||||
|
expect(3);
|
||||||
|
|
||||||
|
var defer = jQuery.Deferred(),
|
||||||
|
piped = defer.pipe( null, function( a, b ) {
|
||||||
|
return jQuery.Deferred(function( defer ) {
|
||||||
|
defer.resolve( a * b );
|
||||||
|
});
|
||||||
|
} ),
|
||||||
|
value1,
|
||||||
|
value2,
|
||||||
|
value3;
|
||||||
|
|
||||||
|
piped.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 );
|
expect( 23 );
|
||||||
|
|
||||||
|
@ -166,13 +286,13 @@ test("jQuery.when()", function() {
|
||||||
|
|
||||||
} , function( message , value ) {
|
} , 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 );
|
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" );
|
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" );
|
||||||
|
|
||||||
|
@ -181,42 +301,48 @@ test("jQuery.when()", function() {
|
||||||
for( i = 1 ; i < 4 ; i++ ) {
|
for( i = 1 ; i < 4 ; i++ ) {
|
||||||
jQuery.when( cache || jQuery.Deferred( function() {
|
jQuery.when( cache || jQuery.Deferred( function() {
|
||||||
this.resolve( i );
|
this.resolve( i );
|
||||||
}) ).then( function( value ) {
|
}) ).done(function( value ) {
|
||||||
strictEqual( value , 1 , "Function executed" + ( i > 1 ? " only once" : "" ) );
|
strictEqual( value , 1 , "Function executed" + ( i > 1 ? " only once" : "" ) );
|
||||||
cache = value;
|
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 ) {
|
var deferreds = {
|
||||||
strictEqual( a , 1 , "Test first param is first resolved value - non-observables" );
|
value: 1,
|
||||||
strictEqual( b , 2 , "Test second param is second resolved value - non-observables" );
|
success: jQuery.Deferred().resolve( 1 ),
|
||||||
strictEqual( c , 3 , "Test third param is third resolved value - non-observables" );
|
error: jQuery.Deferred().reject( 0 ),
|
||||||
}).fail( function() {
|
futureSuccess: jQuery.Deferred(),
|
||||||
ok( false , "Test the created deferred was resolved - non-observables");
|
futureError: jQuery.Deferred()
|
||||||
});
|
},
|
||||||
|
willSucceed = {
|
||||||
|
value: true,
|
||||||
|
success: true,
|
||||||
|
error: false,
|
||||||
|
futureSuccess: true,
|
||||||
|
futureError: false
|
||||||
|
};
|
||||||
|
|
||||||
var successDeferred = jQuery.Deferred().resolve( 1 , 2 , 3 ),
|
jQuery.each( deferreds, function( id1, defer1 ) {
|
||||||
errorDeferred = jQuery.Deferred().reject( "error" , "errorParam" );
|
jQuery.each( deferreds, function( id2, defer2 ) {
|
||||||
|
var shouldResolve = willSucceed[ id1 ] && willSucceed[ id2 ],
|
||||||
jQuery.when( 1 , successDeferred , 3 ).done( function( a, b, c ) {
|
expected = shouldResolve ? [ 1, 1 ] : [ 0, undefined ],
|
||||||
strictEqual( a , 1 , "Test first param is first resolved value - resolved observable" );
|
code = id1 + "/" + id2;
|
||||||
same( b , [ 1 , 2 , 3 ] , "Test second param is second resolved value - resolved observable" );
|
jQuery.when( defer1, defer2 ).done(function( a, b ) {
|
||||||
strictEqual( c , 3 , "Test third param is third resolved value - resolved observable" );
|
if ( shouldResolve ) {
|
||||||
}).fail( function() {
|
same( [ a, b ], expected, code + " => resolve" );
|
||||||
ok( false , "Test the created deferred was resolved - resolved observable");
|
}
|
||||||
});
|
}).fail(function( a, b ) {
|
||||||
|
if ( !shouldResolve ) {
|
||||||
jQuery.when( 1 , errorDeferred , 3 ).done( function() {
|
same( [ a, b ], expected, code + " => resolve" );
|
||||||
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" );
|
|
||||||
});
|
});
|
||||||
} );
|
} );
|
||||||
|
} );
|
||||||
|
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 };
|
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" )
|
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" )
|
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" )
|
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" )
|
if ( t_o == "hide" || t_o == "show" )
|
||||||
equals(cur_o, f_o, "Opacity must be reset to " + f_o + ": " + cur_o);
|
equals(cur_o, f_o, "Opacity must be reset to " + f_o + ": " + cur_o);
|
||||||
|
|
||||||
if ( t_w == "hide" )
|
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 ) {
|
if ( t_o.constructor == Number ) {
|
||||||
equals(cur_o, t_o, "Final opacity should be " + t_o + ": " + cur_o);
|
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 ) {
|
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 ) {
|
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" ) {
|
if ( t_h == "show" ) {
|
||||||
var old_h = jQuery.css(this, "height");
|
var old_h = jQuery.css(elem, "height");
|
||||||
jQuery(this).append("<br/>Some more text<br/>and some more...");
|
jQuery(elem).append("<br/>Some more text<br/>and some more...");
|
||||||
|
|
||||||
if ( /Auto/.test( fn ) ) {
|
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 {
|
} 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
|
// manually remove generated element
|
||||||
jQuery(this).remove();
|
jQuery(elem).remove();
|
||||||
|
|
||||||
start();
|
start();
|
||||||
});
|
});
|
||||||
|
|
|
@ -550,6 +550,47 @@ test("bind(name, false), unbind(name, false)", function() {
|
||||||
jQuery("#main").unbind("click");
|
jQuery("#main").unbind("click");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test("live(name, false), die(name, false)", function() {
|
||||||
|
expect(3);
|
||||||
|
|
||||||
|
var main = 0;
|
||||||
|
jQuery("#main").live("click", function(e){ main++; });
|
||||||
|
jQuery("#ap").trigger("click");
|
||||||
|
equals( main, 1, "Verify that the trigger happened correctly." );
|
||||||
|
|
||||||
|
main = 0;
|
||||||
|
jQuery("#ap").live("click", false);
|
||||||
|
jQuery("#ap").trigger("click");
|
||||||
|
equals( main, 0, "Verify that no bubble happened." );
|
||||||
|
|
||||||
|
main = 0;
|
||||||
|
jQuery("#ap").die("click", false);
|
||||||
|
jQuery("#ap").trigger("click");
|
||||||
|
equals( main, 1, "Verify that the trigger happened correctly." );
|
||||||
|
jQuery("#main").die("click");
|
||||||
|
});
|
||||||
|
|
||||||
|
test("delegate(selector, name, false), undelegate(selector, name, false)", function() {
|
||||||
|
expect(3);
|
||||||
|
|
||||||
|
var main = 0;
|
||||||
|
|
||||||
|
jQuery("#main").delegate("#ap", "click", function(e){ main++; });
|
||||||
|
jQuery("#ap").trigger("click");
|
||||||
|
equals( main, 1, "Verify that the trigger happened correctly." );
|
||||||
|
|
||||||
|
main = 0;
|
||||||
|
jQuery("#ap").delegate("#groups", "click", false);
|
||||||
|
jQuery("#groups").trigger("click");
|
||||||
|
equals( main, 0, "Verify that no bubble happened." );
|
||||||
|
|
||||||
|
main = 0;
|
||||||
|
jQuery("#ap").undelegate("#groups", "click", false);
|
||||||
|
jQuery("#groups").trigger("click");
|
||||||
|
equals( main, 1, "Verify that the trigger happened correctly." );
|
||||||
|
jQuery("#main").undelegate("#ap", "click");
|
||||||
|
});
|
||||||
|
|
||||||
test("bind()/trigger()/unbind() on plain object", function() {
|
test("bind()/trigger()/unbind() on plain object", function() {
|
||||||
expect( 7 );
|
expect( 7 );
|
||||||
|
|
||||||
|
@ -738,10 +779,11 @@ test("trigger() shortcuts", function() {
|
||||||
});
|
});
|
||||||
|
|
||||||
test("trigger() bubbling", function() {
|
test("trigger() bubbling", function() {
|
||||||
expect(14);
|
expect(17);
|
||||||
|
|
||||||
var doc = 0, html = 0, body = 0, main = 0, ap = 0;
|
var win = 0, doc = 0, html = 0, body = 0, main = 0, ap = 0;
|
||||||
|
|
||||||
|
jQuery(window).bind("click", function(e){ win++; });
|
||||||
jQuery(document).bind("click", function(e){ if ( e.target !== document) { doc++; } });
|
jQuery(document).bind("click", function(e){ if ( e.target !== document) { doc++; } });
|
||||||
jQuery("html").bind("click", function(e){ html++; });
|
jQuery("html").bind("click", function(e){ html++; });
|
||||||
jQuery("body").bind("click", function(e){ body++; });
|
jQuery("body").bind("click", function(e){ body++; });
|
||||||
|
@ -749,15 +791,18 @@ test("trigger() bubbling", function() {
|
||||||
jQuery("#ap").bind("click", function(){ ap++; return false; });
|
jQuery("#ap").bind("click", function(){ ap++; return false; });
|
||||||
|
|
||||||
jQuery("html").trigger("click");
|
jQuery("html").trigger("click");
|
||||||
|
equals( win, 1, "HTML bubble" );
|
||||||
equals( doc, 1, "HTML bubble" );
|
equals( doc, 1, "HTML bubble" );
|
||||||
equals( html, 1, "HTML bubble" );
|
equals( html, 1, "HTML bubble" );
|
||||||
|
|
||||||
jQuery("body").trigger("click");
|
jQuery("body").trigger("click");
|
||||||
|
equals( win, 2, "Body bubble" );
|
||||||
equals( doc, 2, "Body bubble" );
|
equals( doc, 2, "Body bubble" );
|
||||||
equals( html, 2, "Body bubble" );
|
equals( html, 2, "Body bubble" );
|
||||||
equals( body, 1, "Body bubble" );
|
equals( body, 1, "Body bubble" );
|
||||||
|
|
||||||
jQuery("#main").trigger("click");
|
jQuery("#main").trigger("click");
|
||||||
|
equals( win, 3, "Main bubble" );
|
||||||
equals( doc, 3, "Main bubble" );
|
equals( doc, 3, "Main bubble" );
|
||||||
equals( html, 3, "Main bubble" );
|
equals( html, 3, "Main bubble" );
|
||||||
equals( body, 2, "Main bubble" );
|
equals( body, 2, "Main bubble" );
|
||||||
|
@ -2010,15 +2055,94 @@ test("focusin bubbles", function() {
|
||||||
jQuery( "body" ).unbind( "focusin.focusinBubblesTest" );
|
jQuery( "body" ).unbind( "focusin.focusinBubblesTest" );
|
||||||
});
|
});
|
||||||
|
|
||||||
/*
|
test("custom events with colons (#3533, #8272)", function() {
|
||||||
test("jQuery(function($) {})", function() {
|
expect(1);
|
||||||
stop();
|
|
||||||
jQuery(function($) {
|
var tab = jQuery("<table><tr><td>trigger</td></tr></table>").appendTo("body");
|
||||||
equals(jQuery, $, "ready doesn't provide an event object, instead it provides a reference to the jQuery function, see http://docs.jquery.com/Events/ready#fn");
|
try {
|
||||||
start();
|
tab.trigger("back:forth");
|
||||||
});
|
ok( true, "colon events don't throw" );
|
||||||
|
} catch ( e ) {
|
||||||
|
ok( false, "colon events die" );
|
||||||
|
};
|
||||||
|
tab.remove();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
(function(){
|
||||||
|
// This code must be run before DOM ready!
|
||||||
|
var notYetReady, noEarlyExecution,
|
||||||
|
order = [],
|
||||||
|
args = {};
|
||||||
|
|
||||||
|
notYetReady = !jQuery.isReady;
|
||||||
|
|
||||||
|
test("jQuery.isReady", function() {
|
||||||
|
expect(2);
|
||||||
|
|
||||||
|
equals(notYetReady, true, "jQuery.isReady should not be true before DOM ready");
|
||||||
|
equals(jQuery.isReady, true, "jQuery.isReady should be true once DOM is ready");
|
||||||
|
});
|
||||||
|
|
||||||
|
// Create an event handler.
|
||||||
|
function makeHandler( testId ) {
|
||||||
|
// When returned function is executed, push testId onto `order` array
|
||||||
|
// to ensure execution order. Also, store event handler arg to ensure
|
||||||
|
// the correct arg is being passed into the event handler.
|
||||||
|
return function( arg ) {
|
||||||
|
order.push(testId);
|
||||||
|
args[testId] = arg;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bind to the ready event in every possible way.
|
||||||
|
jQuery(makeHandler("a"));
|
||||||
|
jQuery(document).ready(makeHandler("b"));
|
||||||
|
jQuery(document).bind("ready.readytest", makeHandler("c"));
|
||||||
|
|
||||||
|
// Do it twice, just to be sure.
|
||||||
|
jQuery(makeHandler("d"));
|
||||||
|
jQuery(document).ready(makeHandler("e"));
|
||||||
|
jQuery(document).bind("ready.readytest", makeHandler("f"));
|
||||||
|
|
||||||
|
noEarlyExecution = order.length == 0;
|
||||||
|
|
||||||
|
// This assumes that QUnit tests are run on DOM ready!
|
||||||
|
test("jQuery ready", function() {
|
||||||
|
expect(10);
|
||||||
|
|
||||||
|
ok(noEarlyExecution, "Handlers bound to DOM ready should not execute before DOM ready");
|
||||||
|
|
||||||
|
// Ensure execution order.
|
||||||
|
same(order, ["a", "b", "d", "e", "c", "f"], "Bound DOM ready handlers should execute in bind-order, but those bound with jQuery(document).bind( 'ready', fn ) will always execute last");
|
||||||
|
|
||||||
|
// Ensure handler argument is correct.
|
||||||
|
equals(args.a, jQuery, "Argument passed to fn in jQuery( fn ) should be jQuery");
|
||||||
|
equals(args.b, jQuery, "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery");
|
||||||
|
ok(args.c instanceof jQuery.Event, "Argument passed to fn in jQuery(document).bind( 'ready', fn ) should be an event object");
|
||||||
|
|
||||||
|
order = [];
|
||||||
|
|
||||||
|
// Now that the ready event has fired, again bind to the ready event
|
||||||
|
// in every possible way. These event handlers should execute immediately.
|
||||||
|
jQuery(makeHandler("g"));
|
||||||
|
equals(order.pop(), "g", "Event handler should execute immediately");
|
||||||
|
equals(args.g, jQuery, "Argument passed to fn in jQuery( fn ) should be jQuery");
|
||||||
|
|
||||||
|
jQuery(document).ready(makeHandler("h"));
|
||||||
|
equals(order.pop(), "h", "Event handler should execute immediately");
|
||||||
|
equals(args.h, jQuery, "Argument passed to fn in jQuery(document).ready( fn ) should be jQuery");
|
||||||
|
|
||||||
|
jQuery(document).bind("ready.readytest", makeHandler("never"));
|
||||||
|
equals(order.length, 0, "Event handler should never execute since DOM ready has already passed");
|
||||||
|
|
||||||
|
// Cleanup.
|
||||||
|
jQuery(document).unbind("ready.readytest");
|
||||||
|
});
|
||||||
|
|
||||||
|
})();
|
||||||
|
|
||||||
|
/*
|
||||||
test("event properties", function() {
|
test("event properties", function() {
|
||||||
stop();
|
stop();
|
||||||
jQuery("#simon1").click(function(event) {
|
jQuery("#simon1").click(function(event) {
|
||||||
|
|
Loading…
Reference in a new issue