Merge branch 'master' of github.com:jquery/jquery into fix-8790-quick-trigger

This commit is contained in:
Dave Methvin 2011-04-10 17:40:31 -04:00
commit bb52010442
26 changed files with 1509 additions and 745 deletions

View file

@ -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?
---------- ----------

View file

@ -248,7 +248,7 @@ jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".sp
jQuery.fn[ o ] = function( f ){ jQuery.fn[ o ] = function( f ){
return this.bind( o, f ); return this.bind( o, f );
}; };
} ); });
jQuery.each( [ "get", "post" ], function( i, method ) { jQuery.each( [ "get", "post" ], function( i, method ) {
jQuery[ method ] = function( url, data, callback, type ) { jQuery[ method ] = function( url, data, callback, type ) {
@ -267,7 +267,7 @@ jQuery.each( [ "get", "post" ], function( i, method ) {
dataType: type dataType: type
}); });
}; };
} ); });
jQuery.extend({ jQuery.extend({
@ -757,7 +757,7 @@ jQuery.extend({
// Serialize the form elements // Serialize the form elements
jQuery.each( a, function() { jQuery.each( a, function() {
add( this.name, this.value ); add( this.name, this.value );
} ); });
} else { } else {
// If traditional, encode the "old" way (the way 1.3.2 or older // If traditional, encode the "old" way (the way 1.3.2 or older

View file

@ -76,6 +76,6 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) {
// Delegate to script // Delegate to script
return "script"; return "script";
} }
} ); });
})( jQuery ); })( jQuery );

View file

@ -25,7 +25,7 @@ jQuery.ajaxPrefilter( "script", function( s ) {
s.type = "GET"; s.type = "GET";
s.global = false; s.global = false;
} }
} ); });
// Bind script tag hack transport // Bind script tag hack transport
jQuery.ajaxTransport( "script", function(s) { jQuery.ajaxTransport( "script", function(s) {
@ -84,6 +84,6 @@ jQuery.ajaxTransport( "script", function(s) {
} }
}; };
} }
} ); });
})( jQuery ); })( jQuery );

View file

@ -3,44 +3,41 @@
var rclass = /[\n\t\r]/g, var rclass = /[\n\t\r]/g,
rspaces = /\s+/, rspaces = /\s+/,
rreturn = /\r/g, rreturn = /\r/g,
rspecialurl = /^(?:href|src|style)$/,
rtype = /^(?:button|input)$/i, rtype = /^(?:button|input)$/i,
rfocusable = /^(?:button|input|object|select|textarea)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i,
rclickable = /^a(?:rea)?$/i, rclickable = /^a(?:rea)?$/i,
rradiocheck = /^(?:radio|checkbox)$/i; formHook;
jQuery.props = {
"for": "htmlFor",
"class": "className",
readonly: "readOnly",
maxlength: "maxLength",
cellspacing: "cellSpacing",
rowspan: "rowSpan",
colspan: "colSpan",
tabindex: "tabIndex",
usemap: "useMap",
frameborder: "frameBorder"
};
jQuery.fn.extend({ jQuery.fn.extend({
attr: function( name, value ) { attr: function( name, value ) {
return jQuery.access( this, name, value, true, jQuery.attr ); return jQuery.access( this, name, value, true, jQuery.attr );
}, },
removeAttr: function( name, fn ) { removeAttr: function( name ) {
return this.each(function(){ return this.each(function() {
jQuery.attr( this, name, "" ); jQuery.removeAttr( this, name );
if ( this.nodeType === 1 ) { });
this.removeAttribute( name ); },
}
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) {
var self = jQuery(this); var self = jQuery(this);
self.addClass( value.call(this, i, self.attr("class")) ); self.addClass( value.call(this, i, self.attr("class") || "") );
}); });
} }
@ -154,82 +151,36 @@ jQuery.fn.extend({
}, },
val: function( value ) { val: function( value ) {
var hooks, ret,
elem = this[0];
if ( !arguments.length ) { if ( !arguments.length ) {
var elem = this[0];
if ( elem ) { if ( elem ) {
if ( jQuery.nodeName( elem, "option" ) ) { hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
// attributes.value is undefined in Blackberry 4.7 but
// uses .value. See #6932 if ( hooks && "get" in hooks && (ret = hooks.get( elem )) !== undefined ) {
var val = elem.attributes.value; return ret;
return !val || val.specified ? elem.value : elem.text;
} }
// We need to handle select boxes special
if ( jQuery.nodeName( elem, "select" ) ) {
var index = elem.selectedIndex,
values = [],
options = elem.options,
one = elem.type === "select-one";
// Nothing was selected
if ( index < 0 ) {
return null;
}
// Loop through all the selected options
for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
var option = options[ i ];
// Don't return options that are disabled or in a disabled optgroup
if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
// Get the specific value for the option
value = jQuery(option).val();
// We don't need an array for one selects
if ( one ) {
return value;
}
// Multi-Selects return an array
values.push( value );
}
}
// Fixes Bug #2551 -- select.val() broken in IE after form.reset()
if ( one && !values.length && options.length ) {
return jQuery( options[ index ] ).val();
}
return values;
}
// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) {
return elem.getAttribute("value") === null ? "on" : elem.value;
}
// Everything else, we just grab the value
return (elem.value || "").replace(rreturn, ""); return (elem.value || "").replace(rreturn, "");
} }
return undefined; return undefined;
} }
var isFunction = jQuery.isFunction(value); var isFunction = jQuery.isFunction( value );
return this.each(function(i) { return this.each(function( i ) {
var self = jQuery(this), val = value; var self = jQuery(this), val;
if ( this.nodeType !== 1 ) { if ( this.nodeType !== 1 ) {
return; return;
} }
if ( isFunction ) { if ( isFunction ) {
val = value.call(this, i, self.val()); val = value.call( this, i, self.val() );
} else {
val = value;
} }
// Treat null/undefined as ""; convert numbers to string // Treat null/undefined as ""; convert numbers to string
@ -237,27 +188,16 @@ jQuery.fn.extend({
val = ""; val = "";
} else if ( typeof val === "number" ) { } else if ( typeof val === "number" ) {
val += ""; val += "";
} else if ( jQuery.isArray(val) ) { } else if ( jQuery.isArray( val ) ) {
val = jQuery.map(val, function (value) { val = jQuery.map(val, function ( value ) {
return value == null ? "" : value + ""; return value == null ? "" : value + "";
}); });
} }
if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
this.checked = jQuery.inArray( self.val(), val ) >= 0;
} else if ( jQuery.nodeName( this, "select" ) ) { // If set returns undefined, fall back to normal setting
var values = jQuery.makeArray(val); if ( !hooks || ("set" in hooks && hooks.set( this, val ) === undefined) ) {
jQuery( "option", this ).each(function() {
this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
});
if ( !values.length ) {
this.selectedIndex = -1;
}
} else {
this.value = val; this.value = val;
} }
}); });
@ -265,6 +205,71 @@ jQuery.fn.extend({
}); });
jQuery.extend({ jQuery.extend({
valHooks: {
option: {
get: function( elem ) {
// attributes.value is undefined in Blackberry 4.7 but
// uses .value. See #6932
var val = elem.attributes.value;
return !val || val.specified ? elem.value : elem.text;
}
},
select: {
get: function( elem ) {
var index = elem.selectedIndex,
values = [],
options = elem.options,
one = elem.type === "select-one";
// Nothing was selected
if ( index < 0 ) {
return null;
}
// Loop through all the selected options
for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) {
var option = options[ i ];
// Don't return options that are disabled or in a disabled optgroup
if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) &&
(!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) {
// Get the specific value for the option
value = jQuery( option ).val();
// We don't need an array for one selects
if ( one ) {
return value;
}
// Multi-Selects return an array
values.push( value );
}
}
// Fixes Bug #2551 -- select.val() broken in IE after form.reset()
if ( one && !values.length && options.length ) {
return jQuery( options[ index ] ).val();
}
return values;
},
set: function( elem, value ) {
var values = jQuery.makeArray( value );
jQuery(elem).find("option").each(function() {
this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
});
if ( !values.length ) {
elem.selectedIndex = -1;
}
return values;
}
}
},
attrFn: { attrFn: {
val: true, val: true,
css: true, css: true,
@ -276,114 +281,265 @@ jQuery.extend({
offset: true offset: true
}, },
attrFix: {
// Always normalize to ensure hook usage
tabindex: "tabIndex",
readonly: "readOnly"
},
attr: function( elem, name, value, pass ) { attr: function( elem, name, value, pass ) {
var nType = elem.nodeType;
// don't get/set attributes on text, comment and attribute nodes // don't get/set attributes on text, comment and attribute nodes
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) { if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return undefined; return undefined;
} }
if ( pass && name in jQuery.attrFn ) { if ( pass && name in jQuery.attrFn ) {
return jQuery(elem)[name](value); return jQuery( elem )[ name ]( value );
} }
var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), var ret, hooks,
// Whether we are setting (or getting) notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
set = value !== undefined;
// Try to normalize/fix the name // Normalize the name if needed
name = notxml && jQuery.props[ name ] || name; name = notxml && jQuery.attrFix[ name ] || name;
// Only do all the following if this is a node (faster for style) // Get the appropriate hook, or the formHook
if ( elem.nodeType === 1 ) { // if getSetAttribute is not supported and we have form objects in IE6/7
// These attributes require special treatment hooks = jQuery.attrHooks[ name ] || ( elem.nodeName === "FORM" && formHook );
var special = rspecialurl.test( name );
// Safari mis-reports the default selected property of an option if ( value !== undefined ) {
// Accessing the parent's selectedIndex property fixes it
if ( name === "selected" && !jQuery.support.optSelected ) {
var parent = elem.parentNode;
if ( parent ) {
parent.selectedIndex;
// Make sure that it also works with optgroups, see #5701 if ( value === null ) {
if ( parent.parentNode ) { jQuery.removeAttr( elem, name );
parent.parentNode.selectedIndex; return undefined;
}
} } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret;
} else {
elem.setAttribute( name, "" + value );
return value;
} }
// If applicable, access the attribute via the DOM 0 way } else {
// 'in' checks fail in Blackberry 4.7 #6931
if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
if ( set ) {
// We can't allow the type property to be changed (since it causes problems in IE)
if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
jQuery.error( "type property can't be changed" );
}
if ( value === null ) { if ( hooks && "get" in hooks && notxml ) {
if ( elem.nodeType === 1 ) { return hooks.get( elem, name );
elem.removeAttribute( name );
}
} else { } else {
elem[ name ] = value;
} ret = elem.getAttribute( name );
// Non-existent attributes return null, we normalize to undefined
return ret === null ?
undefined :
ret;
}
}
},
removeAttr: function( elem, name ) {
if ( elem.nodeType === 1 ) {
name = jQuery.attrFix[ name ] || name;
if ( jQuery.support.getSetAttribute ) {
// Use removeAttribute in browsers that support it
elem.removeAttribute( name );
} else {
jQuery.attr( elem, name, "" );
elem.removeAttributeNode( elem.getAttributeNode( name ) );
}
}
},
attrHooks: {
type: {
set: function( elem, value ) {
// We can't allow the type property to be changed (since it causes problems in IE)
if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
jQuery.error( "type property can't be changed" );
} }
}
// browsers index elements by id/name on forms, give priority to attributes. },
if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { tabIndex: {
return elem.getAttributeNode( name ).nodeValue; get: function( elem ) {
}
// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
if ( name === "tabIndex" ) { var attributeNode = elem.getAttributeNode("tabIndex");
var attributeNode = elem.getAttributeNode( "tabIndex" );
return attributeNode && attributeNode.specified ? return attributeNode && attributeNode.specified ?
attributeNode.value : parseInt( attributeNode.value, 10 ) :
rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
0 : 0 :
undefined; undefined;
} }
}
},
propFix: {},
prop: function( elem, name, value ) {
var nType = elem.nodeType;
// don't get/set properties on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
return undefined;
}
var ret, hooks,
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
// Try to normalize/fix the name
name = notxml && jQuery.propFix[ name ] || name;
hooks = jQuery.propHooks[ name ];
if ( value !== undefined ) {
if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
return ret;
} else {
return (elem[ name ] = value);
}
} else {
if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) {
return ret;
} else {
return elem[ name ]; return elem[ name ];
} }
}
},
if ( !jQuery.support.style && notxml && name === "style" ) { propHooks: {}
if ( set ) { });
elem.style.cssText = "" + value;
// IE6/7 do not support getting/setting some attributes with get/setAttribute
if ( !jQuery.support.getSetAttribute ) {
jQuery.attrFix = jQuery.extend( jQuery.attrFix, {
"for": "htmlFor",
"class": "className",
maxlength: "maxLength",
cellspacing: "cellSpacing",
rowspan: "rowSpan",
colspan: "colSpan",
usemap: "useMap",
frameborder: "frameBorder"
});
// Use this for any attribute on a form in IE6/7
// And the name attribute
formHook = jQuery.attrHooks.name = {
get: function( elem, name ) {
var ret = elem.getAttributeNode( name );
// Return undefined if not specified instead of empty string
return ret && ret.specified ?
ret.nodeValue :
undefined;
},
set: function( elem, value, name ) {
// Check form objects in IE (multiple bugs related)
// Only use nodeValue if the attribute node exists on the form
var ret = elem.getAttributeNode( name );
if ( ret ) {
ret.nodeValue = value;
return value;
}
}
};
// Set width and height to auto instead of 0 on empty string( Bug #8150 )
// This is for removals
jQuery.each([ "width", "height" ], function( i, name ) {
jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
set: function( elem, value ) {
if ( value === "" ) {
elem.setAttribute( name, "auto" );
return value;
} }
return elem.style.cssText;
} }
});
});
}
if ( set ) { // Remove certain attrs if set to false
// convert the value to a string (all browsers do this but IE) see #1070 jQuery.each([ "selected", "checked", "readOnly", "disabled" ], function( i, name ) {
elem.setAttribute( name, "" + value ); jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
set: function( elem, value ) {
if ( value === false ) {
jQuery.removeAttr( elem, name );
return value;
} }
// Ensure that missing attributes return undefined
// Blackberry 4.7 returns "" from getAttribute #6938
if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
return undefined;
}
var attr = !jQuery.support.hrefNormalized && notxml && special ?
// Some attributes require a special call on IE
elem.getAttribute( name, 2 ) :
elem.getAttribute( name );
// Non-existent attributes return null, we normalize to undefined
return attr === null ? undefined : attr;
} }
// Handle everything which isn't a DOM element node });
if ( set ) { });
elem[ name ] = value;
// Some attributes require a special call on IE
if ( !jQuery.support.hrefNormalized ) {
jQuery.each([ "href", "src", "width", "height", "list" ], function( i, name ) {
jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
get: function( elem ) {
var ret = elem.getAttribute( name, 2 );
return ret === null ? undefined : ret;
}
});
});
}
if ( !jQuery.support.style ) {
jQuery.attrHooks.style = {
get: function( elem ) {
// Return undefined in the case of empty string
// Normalize to lowercase since IE uppercases css property names
return elem.style.cssText.toLowerCase() || undefined;
},
set: function( elem, value ) {
return (elem.style.cssText = "" + value);
} }
return elem[ name ]; };
} }
// Safari mis-reports the default selected property of an option
// Accessing the parent's selectedIndex property fixes it
if ( !jQuery.support.optSelected ) {
jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, {
get: function( elem ) {
var parent = elem.parentNode;
if ( parent ) {
parent.selectedIndex;
// Make sure that it also works with optgroups, see #5701
if ( parent.parentNode ) {
parent.parentNode.selectedIndex;
}
}
}
});
}
// Radios and checkboxes getter/setter
if ( !jQuery.support.checkOn ) {
jQuery.each([ "radio", "checkbox" ], function() {
jQuery.valHooks[ this ] = {
get: function( elem ) {
// Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified
return elem.getAttribute("value") === null ? "on" : elem.value;
}
};
});
}
jQuery.each([ "radio", "checkbox" ], function() {
jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], {
set: function( elem, value ) {
if ( jQuery.isArray( value ) ) {
return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0);
}
}
});
}); });
})( jQuery ); })( jQuery );

View file

@ -88,7 +88,7 @@ jQuery.fn = jQuery.prototype = {
if ( selector === "body" && !context && document.body ) { if ( selector === "body" && !context && document.body ) {
this.context = document; this.context = document;
this[0] = document.body; this[0] = document.body;
this.selector = "body"; this.selector = selector;
this.length = 1; this.length = 1;
return this; return this;
} }
@ -374,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 );
@ -561,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 );
} }
}, },
@ -661,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++ ) {
@ -712,15 +710,30 @@ jQuery.extend({
// arg is for internal usage only // arg is for internal usage only
map: function( elems, callback, arg ) { map: function( elems, callback, arg ) {
var ret = [], value; var value, key, ret = [],
i = 0,
length = elems.length,
// jquery objects are treated as arrays
isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || jQuery.isArray( elems ) ) ;
// Go through the array, translating each of the items to their // Go through the array, translating each of the items to their
// new value (or values). if ( isArray ) {
for ( var i = 0, length = elems.length; i < length; i++ ) { for ( ; i < length; i++ ) {
value = callback( elems[ i ], i, arg ); value = callback( elems[ i ], i, arg );
if ( value != null ) { if ( value != null ) {
ret[ ret.length ] = value; ret[ ret.length ] = value;
}
}
// Go thorugh every key on the object,
} else {
for ( key in elems ) {
value = callback( elems[ key ], key, arg );
if ( value != null ) {
ret[ ret.length ] = value;
}
} }
} }
@ -731,31 +744,52 @@ jQuery.extend({
// A global GUID counter for objects // A global GUID counter for objects
guid: 1, guid: 1,
proxy: function( fn, proxy, thisObject ) { // Bind a function to a context, optionally partially applying any
if ( arguments.length === 2 ) { // arguments.
if ( typeof proxy === "string" ) { proxy: function( fn, context ) {
thisObject = fn; var args, proxy;
fn = thisObject[ proxy ];
proxy = undefined;
} else if ( proxy && !jQuery.isFunction( proxy ) ) { // XXX BACKCOMPAT: Support old string method.
thisObject = proxy; if ( typeof context === "string" ) {
proxy = undefined; fn = fn[ context ];
context = arguments[0];
}
// Quick check to determine if target is callable, in the spec
// this throws a TypeError, but we will just return undefined.
if ( ! jQuery.isFunction( fn ) ) {
return undefined;
}
if ( jQuery.support.nativeBind ) {
// Native bind
args = slice.call( arguments, 1 );
if ( args.length ) {
proxy = Function.prototype.bind.apply( fn, args );
} else {
proxy = fn.bind( context );
}
} else {
// Simulated bind
args = slice.call( arguments, 2 );
if ( args.length ) {
proxy = function() {
return arguments.length ?
fn.apply( context, args.concat( slice.call( arguments ) ) ) :
fn.apply( context, args );
};
} else {
proxy = function() {
return arguments.length ?
fn.apply( context, arguments ) :
fn.call( context );
};
} }
} }
if ( !proxy && fn ) {
proxy = function() {
return fn.apply( thisObject || this, arguments );
};
}
// Set the guid of unique handler to the same of original handler, so it can be removed // Set the guid of unique handler to the same of original handler, so it can be removed
if ( fn ) { proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
}
// So proxy can be declared as an argument
return proxy; return proxy;
}, },
@ -846,12 +880,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]+/;

View file

@ -1,6 +1,7 @@
(function( jQuery ) { (function( jQuery ) {
var rbrace = /^(?:\{.*\}|\[.*\])$/; var rbrace = /^(?:\{.*\}|\[.*\])$/,
rmultiDash = /([a-z])([A-Z])/g;
jQuery.extend({ jQuery.extend({
cache: {}, cache: {},
@ -223,12 +224,13 @@ jQuery.fn.extend({
data = jQuery.data( this[0] ); data = jQuery.data( this[0] );
if ( this[0].nodeType === 1 ) { if ( this[0].nodeType === 1 ) {
var attr = this[0].attributes, name; var attr = this[0].attributes, name;
for ( var i = 0, l = attr.length; i < l; i++ ) { for ( var i = 0, l = attr.length; i < l; i++ ) {
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 {

View file

@ -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 ) {
@ -119,7 +146,7 @@ jQuery.extend({
} }
return obj; return obj;
} }
} ); });
// Make sure only one callback list will be used // Make sure only one callback list will be used
deferred.done( failDeferred.cancel ).fail( deferred.cancel ); deferred.done( failDeferred.cancel ).fail( deferred.cancel );
// Unexpose cancel // Unexpose cancel

40
src/effects.js vendored
View file

@ -11,7 +11,20 @@ var elemdisplay = {},
[ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ],
// opacity animations // opacity animations
[ "opacity" ] [ "opacity" ]
]; ],
fxNow,
requestAnimationFrame = window.webkitRequestAnimationFrame ||
window.mozRequestAnimationFrame ||
window.oRequestAnimationFrame;
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 ) {
@ -347,9 +360,10 @@ jQuery.fx.prototype = {
// Start an animation from one number to another // Start an animation from one number to another
custom: function( from, to, unit ) { custom: function( from, to, unit ) {
var self = this, var self = this,
fx = jQuery.fx; fx = jQuery.fx,
raf;
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" );
@ -363,7 +377,20 @@ jQuery.fx.prototype = {
t.elem = this.elem; t.elem = this.elem;
if ( t() && jQuery.timers.push(t) && !timerId ) { if ( t() && jQuery.timers.push(t) && !timerId ) {
timerId = setInterval(fx.tick, fx.interval); // Use requestAnimationFrame instead of setInterval if available
if ( requestAnimationFrame ) {
timerId = 1;
raf = function() {
// When timerId gets set to null at any point, this stops
if ( timerId ) {
requestAnimationFrame( raf );
fx.tick();
}
};
requestAnimationFrame( raf );
} else {
timerId = setInterval( fx.tick, fx.interval );
}
} }
}, },
@ -394,7 +421,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;
@ -417,7 +445,7 @@ jQuery.fx.prototype = {
jQuery.each( [ "", "X", "Y" ], function (index, value) { jQuery.each( [ "", "X", "Y" ], function (index, value) {
elem.style[ "overflow" + value ] = options.overflow[index]; elem.style[ "overflow" + value ] = options.overflow[index];
} ); });
} }
// Hide the element if the "hide" operation was done // Hide the element if the "hide" operation was done

View file

@ -1,6 +1,7 @@
(function( jQuery ) { (function( jQuery ) {
var rnamespaces = /\.(.*)$/, var hasOwn = Object.prototype.hasOwnProperty,
rnamespaces = /\.(.*)$/,
rformElems = /^(?:textarea|input|select)$/i, rformElems = /^(?:textarea|input|select)$/i,
rperiod = /\./g, rperiod = /\./g,
rspace = / /g, rspace = / /g,
@ -288,9 +289,7 @@ jQuery.event = {
trigger: function( event, data, elem ) { trigger: function( event, data, elem ) {
// Event object or event type // Event object or event type
var type = event.type || event, var type = event.type || event,
ontype = "on" + type, namespaces = [];
namespaces = [],
cur = elem;
event = typeof event === "object" ? event = typeof event === "object" ?
// jQuery.Event object // jQuery.Event object
@ -355,6 +354,10 @@ jQuery.event = {
data = jQuery.makeArray( data ); data = jQuery.makeArray( data );
data.unshift( event ); data.unshift( event );
var cur = elem,
// IE doesn't like method names with a colon (#3533, #8272)
ontype = type.indexOf(":") < 0? "on" + type : "";
// Fire event on the current element, then bubble up the DOM tree // Fire event on the current element, then bubble up the DOM tree
do { do {
var handle = jQuery._data( cur, "handle" ); var handle = jQuery._data( cur, "handle" );
@ -364,13 +367,11 @@ jQuery.event = {
handle.apply( cur, data ); handle.apply( cur, data );
} }
// Trigger an inline bound script; IE<9 dies on special-char event name // Trigger an inline bound script
try { if ( ontype &&jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) {
if ( jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) { event.result = false;
event.result = false; event.preventDefault();
event.preventDefault(); }
}
} catch ( ieError1 ) {}
// Bubble up to document, then to window // Bubble up to document, then to window
cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window; cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window;
@ -386,9 +387,9 @@ jQuery.event = {
// Call a native DOM method on the target with the same name name as the event. // 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. // Can't use an .isFunction)() check here because IE6/7 fails that test.
// Use try/catch so IE<9 won't die on special-char event name or hidden element (#3533). // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch.
try { try {
if ( elem[ type ] ) { if ( ontype && elem[ type ] ) {
// Don't re-trigger an onFOO event when we call its FOO() method // Don't re-trigger an onFOO event when we call its FOO() method
old = elem[ ontype ]; old = elem[ ontype ];
@ -399,7 +400,7 @@ jQuery.event = {
jQuery.event.triggered = type; jQuery.event.triggered = type;
elem[ type ](); elem[ type ]();
} }
} catch ( ieError2 ) {} } catch ( ieError ) {}
if ( old ) { if ( old ) {
elem[ ontype ] = old; elem[ ontype ] = old;
@ -576,7 +577,15 @@ jQuery.Event = function( src ) {
// Event object // Event object
if ( src && src.type ) { if ( src && src.type ) {
this.originalEvent = src; this.originalEvent = src;
this.type = src.type;
// Push explicitly provided properties onto the event object
for ( var prop in src ) {
// Ensure we don't clobber jQuery.Event prototype
// with own properties.
if ( hasOwn.call( src, prop ) ) {
this[ prop ] = src[ prop ];
}
}
// Events bubbling up the document may have been marked as prevented // Events bubbling up the document may have been marked as prevented
// by a handler lower down the tree; reflect the correct value. // by a handler lower down the tree; reflect the correct value.
@ -898,6 +907,8 @@ if ( !jQuery.support.focusinBubbles ) {
jQuery.each(["bind", "one"], function( i, name ) { jQuery.each(["bind", "one"], function( i, name ) {
jQuery.fn[ name ] = function( type, data, fn ) { jQuery.fn[ name ] = function( type, data, fn ) {
var handler;
// Handle object literals // Handle object literals
if ( typeof type === "object" ) { if ( typeof type === "object" ) {
for ( var key in type ) { for ( var key in type ) {
@ -911,10 +922,15 @@ jQuery.each(["bind", "one"], function( i, name ) {
data = undefined; data = undefined;
} }
var handler = name === "one" ? jQuery.proxy( fn, function( event ) { if ( name === "one" ) {
jQuery( this ).unbind( event, handler ); handler = function( event ) {
return fn.apply( this, arguments ); jQuery( this ).unbind( event, handler );
}) : fn; return fn.apply( this, arguments );
};
handler.guid = fn.guid || jQuery.guid++;
} else {
handler = fn;
}
if ( type === "unload" && name !== "one" ) { if ( type === "unload" && name !== "one" ) {
this.one( type, data, fn ); this.one( type, data, fn );
@ -978,24 +994,27 @@ jQuery.fn.extend({
toggle: function( fn ) { toggle: function( fn ) {
// Save reference to arguments for access in closure // Save reference to arguments for access in closure
var args = arguments, var args = arguments,
i = 1; guid = fn.guid || jQuery.guid++,
i = 0,
toggler = function( event ) {
// Figure out which function to execute
var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i;
jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 );
// Make sure that clicks stop
event.preventDefault();
// and execute the function
return args[ lastToggle ].apply( this, arguments ) || false;
};
// link all the functions, so any of them can unbind this click handler // link all the functions, so any of them can unbind this click handler
toggler.guid = guid;
while ( i < args.length ) { while ( i < args.length ) {
jQuery.proxy( fn, args[ i++ ] ); args[ i++ ].guid = guid;
} }
return this.click( jQuery.proxy( fn, function( event ) { return this.click( toggler );
// Figure out which function to execute
var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i;
jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 );
// Make sure that clicks stop
event.preventDefault();
// and execute the function
return args[ lastToggle ].apply( this, arguments ) || false;
}));
}, },
hover: function( fnOver, fnOut ) { hover: function( fnOver, fnOut ) {
@ -1181,3 +1200,4 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
}); });
})( jQuery ); })( jQuery );

View file

@ -377,7 +377,7 @@ function cloneCopyEvent( src, dest ) {
} }
} }
function cloneFixAttributes(src, dest) { function cloneFixAttributes( src, dest ) {
// We do not need to do anything for non-Elements // We do not need to do anything for non-Elements
if ( dest.nodeType !== 1 ) { if ( dest.nodeType !== 1 ) {
return; return;
@ -549,7 +549,8 @@ jQuery.extend({
// Return the cloned set // Return the cloned set
return clone; return clone;
}, },
clean: function( elems, context, fragment, scripts ) { clean: function( elems, context, fragment, scripts ) {
context = context || document; context = context || document;

View file

@ -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 c50b0cddec48494ba882606d03e14cce647d243b

View file

@ -1,44 +1,59 @@
(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.setAttribute("className", "t");
div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
div.style.display = "none"; all = div.getElementsByTagName( "*" );
div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>"; a = div.getElementsByTagName( "a" )[ 0 ];
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
tbody: !div.getElementsByTagName("tbody").length, tbody: !div.getElementsByTagName( "tbody" ).length,
// Make sure that link elements get serialized correctly by innerHTML // Make sure that link elements get serialized correctly by innerHTML
// This requires a wrapper element in IE // This requires a wrapper element in IE
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 insted) // (IE uses .cssText instead)
style: /red/.test( a.getAttribute("style") ), style: /top/.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)
@ -52,183 +67,167 @@
// 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)
optSelected: opt.selected, optSelected: opt.selected,
// Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7)
getSetAttribute: div.className !== "t",
// Test for presence of native Function#bind.
// Not in: >= Chrome 6, >= FireFox 3, Safari 5?, IE 9?, Opera 11?
nativeBind: jQuery.isFunction( Function.prototype.bind ),
// 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) { support.deleteExpando = false;
jQuery.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 div.style.width = div.style.paddingLeft = "1px";
jQuery(function() {
var div = document.createElement("div"),
body = document.getElementsByTagName("body")[0];
// Frameset documents with no body should not run this code // We use our own, invisible, body
if ( !body ) { body = document.createElement( "body" );
return; 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"; support.boxModel = div.offsetWidth === 2;
body.appendChild( div );
jQuery.boxModel = jQuery.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
// elements when setting their display to 'inline' and giving // elements when setting their display to 'inline' and giving
// them layout // them layout
// (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
// table row; if so, offsetWidth/Height are not reliable for use when // table row; if so, offsetWidth/Height are not reliable for use when
// determining if an element has been hidden directly using // determining if an element has been hidden directly using
// 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
// gets computed margin-right based on width of container. For more // gets computed margin-right based on width of container. For more
// info see bug #3333 // info see bug #3333
// Fails in WebKit before Feb 2011 nightlies // Fails in WebKit before Feb 2011 nightlies
// WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right
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 ) { // We only care about the case where non-standard event systems
var el = document.createElement("div"); // are used, namely in IE. Short-circuiting here helps us to
eventName = "on" + eventName; // avoid an eval call (in setAttribute) which can cause CSP
// to go haywire. See: https://developer.mozilla.org/en/Security/CSP
// We only care about the case where non-standard event systems if ( div.attachEvent ) {
// are used, namely in IE. Short-circuiting here helps us to for( i in {
// avoid an eval call (in setAttribute) which can cause CSP submit: 1,
// to go haywire. See: https://developer.mozilla.org/en/Security/CSP change: 1,
if ( !el.attachEvent ) { focusin: 1
return true; } ) {
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 // 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 );

View file

@ -17,17 +17,30 @@ var runtil = /Until$/,
jQuery.fn.extend({ jQuery.fn.extend({
find: function( selector ) { find: function( selector ) {
var ret = this.pushStack( "", "find", selector ), var self = this,
length = 0; i, l;
for ( var i = 0, l = this.length; i < l; i++ ) { if ( typeof selector !== "string" ) {
return jQuery( selector ).filter(function() {
for ( i = 0, l = self.length; i < l; i++ ) {
if ( jQuery.contains( self[ i ], this ) ) {
return true;
}
}
});
}
var ret = this.pushStack( "", "find", selector ),
length, n, r;
for ( i = 0, l = this.length; i < l; i++ ) {
length = ret.length; length = ret.length;
jQuery.find( selector, this[i], ret ); jQuery.find( selector, this[i], ret );
if ( i > 0 ) { if ( i > 0 ) {
// Make sure that the results are unique // Make sure that the results are unique
for ( var n = length; n < ret.length; n++ ) { for ( n = length; n < ret.length; n++ ) {
for ( var r = 0; r < length; r++ ) { for ( r = 0; r < length; r++ ) {
if ( ret[r] === ret[n] ) { if ( ret[r] === ret[n] ) {
ret.splice(n--, 1); ret.splice(n--, 1);
break; break;
@ -60,12 +73,15 @@ jQuery.fn.extend({
}, },
is: function( selector ) { is: function( selector ) {
return !!selector && jQuery.filter( selector, this ).length > 0; return !!selector && (typeof selector === "string" ?
jQuery.filter( selector, this ).length > 0 :
this.filter( selector ).length > 0);
}, },
closest: function( selectors, context ) { closest: function( selectors, context ) {
var ret = [], i, l, cur = this[0]; var ret = [], i, l, cur = this[0];
// Array
if ( jQuery.isArray( selectors ) ) { if ( jQuery.isArray( selectors ) ) {
var match, selector, var match, selector,
matches = {}, matches = {},
@ -75,8 +91,8 @@ jQuery.fn.extend({
for ( i = 0, l = selectors.length; i < l; i++ ) { for ( i = 0, l = selectors.length; i < l; i++ ) {
selector = selectors[i]; selector = selectors[i];
if ( !matches[selector] ) { if ( !matches[ selector ] ) {
matches[selector] = jQuery.expr.match.POS.test( selector ) ? matches[ selector ] = POS.test( selector ) ?
jQuery( selector, context || this.context ) : jQuery( selector, context || this.context ) :
selector; selector;
} }
@ -84,9 +100,9 @@ jQuery.fn.extend({
while ( cur && cur.ownerDocument && cur !== context ) { while ( cur && cur.ownerDocument && cur !== context ) {
for ( selector in matches ) { for ( selector in matches ) {
match = matches[selector]; match = matches[ selector ];
if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) {
ret.push({ selector: selector, elem: cur, level: level }); ret.push({ selector: selector, elem: cur, level: level });
} }
} }
@ -99,8 +115,10 @@ jQuery.fn.extend({
return ret; return ret;
} }
var pos = POS.test( selectors ) ? // String
jQuery( selectors, context || this.context ) : null; var pos = POS.test( selectors ) || typeof selectors !== "string" ?
jQuery( selectors, context || this.context ) :
0;
for ( i = 0, l = this.length; i < l; i++ ) { for ( i = 0, l = this.length; i < l; i++ ) {
cur = this[i]; cur = this[i];
@ -112,14 +130,14 @@ jQuery.fn.extend({
} else { } else {
cur = cur.parentNode; cur = cur.parentNode;
if ( !cur || !cur.ownerDocument || cur === context ) { if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
break; break;
} }
} }
} }
} }
ret = ret.length > 1 ? jQuery.unique(ret) : ret; ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
return this.pushStack( ret, "closest", selectors ); return this.pushStack( ret, "closest", selectors );
}, },
@ -286,7 +304,7 @@ function winnow( elements, qualifier, keep ) {
return retVal === keep; return retVal === keep;
}); });
} else if ( qualifier.nodeType ) { } else if ( qualifier && qualifier.nodeType ) {
return jQuery.grep(elements, function( elem, i ) { return jQuery.grep(elements, function( elem, i ) {
return (elem === qualifier) === keep; return (elem === qualifier) === keep;
}); });

View file

@ -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);
} }
} }

View file

@ -203,6 +203,10 @@ Z</textarea>
<select name="D4" disabled="disabled"> <select name="D4" disabled="disabled">
<option selected="selected" value="NO">NO</option> <option selected="selected" value="NO">NO</option>
</select> </select>
<input id="list-test" type="text" />
<datalist id="datalist">
<option value="option"></option>
</datalist>
</form> </form>
<div id="moretests"> <div id="moretests">
<form> <form>

View file

@ -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>

View file

@ -3,38 +3,81 @@ module("attributes", { teardown: moduleTeardown });
var bareObj = function(value) { return value; }; var bareObj = function(value) { return value; };
var functionReturningObj = function(value) { return (function() { return value; }); }; var functionReturningObj = function(value) { return (function() { return value; }); };
test("jQuery.props: itegrity test", function() {
expect(1); test("jQuery.attrFix integrity test", function() {
expect(1);
// This must be maintained and equal jQuery.props // This must be maintained and equal jQuery.attrFix when appropriate
// Ensure that accidental or erroneous property // Ensure that accidental or erroneous property
// overwrites don't occur // overwrites don't occur
// This is simply for better code coverage and future proofing. // This is simply for better code coverage and future proofing.
var propsShouldBe = { var propsShouldBe;
"for": "htmlFor", if ( !jQuery.support.getSetAttribute ) {
"class": "className", propsShouldBe = {
readonly: "readOnly", tabindex: "tabIndex",
maxlength: "maxLength", readonly: "readOnly",
cellspacing: "cellSpacing", "for": "htmlFor",
rowspan: "rowSpan", "class": "className",
colspan: "colSpan", maxlength: "maxLength",
tabindex: "tabIndex", cellspacing: "cellSpacing",
usemap: "useMap", rowspan: "rowSpan",
frameborder: "frameBorder" colspan: "colSpan",
}; usemap: "useMap",
frameborder: "frameBorder"
};
} else {
propsShouldBe = {
tabindex: "tabIndex",
readonly: "readOnly"
};
}
same(propsShouldBe, jQuery.props, "jQuery.props passes integrity check"); same(propsShouldBe, jQuery.attrFix, "jQuery.attrFix passes integrity check");
});
test("prop(String, Object)", function() {
expect(19);
equals( jQuery('#text1').prop('value'), "Test", 'Check for value attribute' );
equals( jQuery('#text1').prop('value', "Test2").prop('defaultValue'), "Test", 'Check for defaultValue attribute' );
equals( jQuery('#select2').prop('selectedIndex'), 3, 'Check for selectedIndex attribute' );
equals( jQuery('#foo').prop('nodeName').toUpperCase(), 'DIV', 'Check for nodeName attribute' );
equals( jQuery('#foo').prop('tagName').toUpperCase(), 'DIV', 'Check for tagName attribute' );
equals( jQuery("<option/>").prop("selected"), false, "Check selected attribute on disconnected element." );
var body = document.body, $body = jQuery( body );
ok( $body.prop('nextSibling') === null, 'Make sure a null expando returns null' );
body.foo = 'bar';
equals( $body.prop('foo'), 'bar', 'Make sure the expando is preferred over the dom attribute' );
body.foo = undefined;
ok( $body.prop('foo') === undefined, 'Make sure the expando is preferred over the dom attribute, even if undefined' );
var select = document.createElement("select"), optgroup = document.createElement("optgroup"), option = document.createElement("option");
optgroup.appendChild( option );
select.appendChild( optgroup );
equals( jQuery(option).prop("selected"), true, "Make sure that a single option is selected, even when in an optgroup." );
equals( jQuery(document).prop("nodeName"), "#document", "prop works correctly on document nodes (bug #7451)." );
var attributeNode = document.createAttribute("irrelevant"),
commentNode = document.createComment("some comment"),
textNode = document.createTextNode("some text"),
obj = {};
jQuery.each( [document, attributeNode, commentNode, textNode, obj, "#firstp"], function( i, ele ) {
strictEqual( jQuery(ele).prop("nonexisting"), undefined, "prop works correctly for non existing attributes (bug #7500)." );
});
var obj = {};
jQuery.each( [document, obj], function( i, ele ) {
var $ele = jQuery( ele );
$ele.prop( "nonexisting", "foo" );
equal( $ele.prop("nonexisting"), "foo", "prop(name, value) works correctly for non existing attributes (bug #7500)." );
});
jQuery( document ).removeProp("nonexisting");
}); });
test("attr(String)", function() { test("attr(String)", function() {
expect(37); expect(32);
// This one sometimes fails randomly ?!
equals( jQuery('#text1').attr('value'), "Test", 'Check for value attribute' );
equals( jQuery('#text1').attr('value', "Test2").attr('defaultValue'), "Test", 'Check for defaultValue attribute' );
equals( jQuery('#text1').attr('type'), "text", 'Check for type attribute' ); equals( jQuery('#text1').attr('type'), "text", 'Check for type attribute' );
equals( jQuery('#radio1').attr('type'), "radio", 'Check for type attribute' ); equals( jQuery('#radio1').attr('type'), "radio", 'Check for type attribute' );
equals( jQuery('#check1').attr('type'), "checkbox", 'Check for type attribute' ); equals( jQuery('#check1').attr('type'), "checkbox", 'Check for type attribute' );
@ -46,60 +89,54 @@ test("attr(String)", function() {
equals( jQuery('#name').attr('name'), "name", 'Check for name attribute' ); equals( jQuery('#name').attr('name'), "name", 'Check for name attribute' );
equals( jQuery('#text1').attr('name'), "action", 'Check for name attribute' ); equals( jQuery('#text1').attr('name'), "action", 'Check for name attribute' );
ok( jQuery('#form').attr('action').indexOf("formaction") >= 0, 'Check for action attribute' ); ok( jQuery('#form').attr('action').indexOf("formaction") >= 0, 'Check for action attribute' );
// Temporarily disabled. See: #4299 equals( jQuery('#form').attr('blah', 'blah').attr('blah'), 'blah', 'Set non-existant attribute on a form' );
// ok( jQuery('#form').attr('action','newformaction').attr('action').indexOf("newformaction") >= 0, 'Check that action attribute was changed' ); equals( jQuery('#foo').attr('height'), undefined, 'Non existent height attribute should return undefined' );
// [7472] & [3113] (form contains an input with name="action" or name="id")
var extras = jQuery('<input name="id" name="name" /><input id="target" name="target" />').appendTo('#testForm');
equals( jQuery('#form').attr('action','newformaction').attr('action'), 'newformaction', 'Check that action attribute was changed' );
equals( jQuery('#testForm').attr('target'), undefined, 'Retrieving target does not equal the input with name=target' );
equals( jQuery('#testForm').attr('target', 'newTarget').attr('target'), 'newTarget', 'Set target successfully on a form' );
equals( jQuery('#testForm').removeAttr('id').attr('id'), undefined, 'Retrieving id does not equal the input with name=id after id is removed [#7472]' );
// Bug #3685 (form contains input with name="name")
equals( jQuery('#testForm').attr('name'), undefined, 'Retrieving name does not retrieve input with name=name' );
extras.remove();
equals( jQuery('#text1').attr('maxlength'), '30', 'Check for maxlength attribute' ); equals( jQuery('#text1').attr('maxlength'), '30', 'Check for maxlength attribute' );
equals( jQuery('#text1').attr('maxLength'), '30', 'Check for maxLength attribute' ); equals( jQuery('#text1').attr('maxLength'), '30', 'Check for maxLength attribute' );
equals( jQuery('#area1').attr('maxLength'), '30', 'Check for maxLength attribute' ); equals( jQuery('#area1').attr('maxLength'), '30', 'Check for maxLength attribute' );
equals( jQuery('#select2').attr('selectedIndex'), 3, 'Check for selectedIndex attribute' );
equals( jQuery('#foo').attr('nodeName').toUpperCase(), 'DIV', 'Check for nodeName attribute' );
equals( jQuery('#foo').attr('tagName').toUpperCase(), 'DIV', 'Check for tagName attribute' );
// using innerHTML in IE causes href attribute to be serialized to the full path // using innerHTML in IE causes href attribute to be serialized to the full path
jQuery('<a/>').attr({ 'id': 'tAnchor5', 'href': '#5' }).appendTo('#main'); jQuery('<a/>').attr({ 'id': 'tAnchor5', 'href': '#5' }).appendTo('#main');
equals( jQuery('#tAnchor5').attr('href'), "#5", 'Check for non-absolute href (an anchor)' ); equals( jQuery('#tAnchor5').attr('href'), "#5", 'Check for non-absolute href (an anchor)' );
equals( jQuery("<option/>").attr("selected"), false, "Check selected attribute on disconnected element." ); // list attribute is readonly by default in browsers that support it
jQuery('#list-test').attr('list', 'datalist');
equals( jQuery('#list-test').attr('list'), 'datalist', 'Check setting list attribute' );
// Related to [5574] and [5683] // Related to [5574] and [5683]
var body = document.body, $body = jQuery(body); var body = document.body, $body = jQuery(body);
ok( $body.attr('foo') === undefined, 'Make sure that a non existent attribute returns undefined' ); strictEqual( $body.attr('foo'), undefined, 'Make sure that a non existent attribute returns undefined' );
ok( $body.attr('nextSibling') === null, 'Make sure a null expando returns null' );
body.setAttribute('foo', 'baz'); body.setAttribute('foo', 'baz');
equals( $body.attr('foo'), 'baz', 'Make sure the dom attribute is retrieved when no expando is found' ); equals( $body.attr('foo'), 'baz', 'Make sure the dom attribute is retrieved when no expando is found' );
body.foo = 'bar';
equals( $body.attr('foo'), 'bar', 'Make sure the expando is preferred over the dom attribute' );
$body.attr('foo','cool'); $body.attr('foo','cool');
equals( $body.attr('foo'), 'cool', 'Make sure that setting works well when both expando and dom attribute are available' ); equals( $body.attr('foo'), 'cool', 'Make sure that setting works well when both expando and dom attribute are available' );
body.foo = undefined;
ok( $body.attr('foo') === undefined, 'Make sure the expando is preferred over the dom attribute, even if undefined' );
body.removeAttribute('foo'); // Cleanup body.removeAttribute('foo'); // Cleanup
var select = document.createElement("select"), optgroup = document.createElement("optgroup"), option = document.createElement("option"); var $img = jQuery('<img style="display:none" width="215" height="53" src="http://static.jquery.com/files/rocker/images/logo_jquery_215x53.gif"/>').appendTo('body');
optgroup.appendChild( option ); equals( $img.attr('width'), "215", "Retrieve width attribute an an element with display:none." );
select.appendChild( optgroup ); equals( $img.attr('height'), "53", "Retrieve height attribute an an element with display:none." );
equals( jQuery(option).attr("selected"), true, "Make sure that a single option is selected, even when in an optgroup." ); // Check for style support
ok( !!~jQuery('#dl').attr('style').indexOf('position'), 'Check style attribute getter, also normalize css props to lowercase' );
ok( !!~jQuery('#foo').attr('style', 'position:absolute;').attr('style').indexOf('position'), 'Check style setter' );
ok( jQuery("<div/>").attr("doesntexist") === undefined, "Make sure undefined is returned when no attribute is found." ); ok( jQuery("<div/>").attr("doesntexist") === undefined, "Make sure undefined is returned when no attribute is found." );
ok( jQuery().attr("doesntexist") === undefined, "Make sure undefined is returned when no element is there." ); ok( jQuery().attr("doesntexist") === undefined, "Make sure undefined is returned when no element is there." );
equals( jQuery(document).attr("nodeName"), "#document", "attr works correctly on document nodes (bug #7451)." );
var attributeNode = document.createAttribute("irrelevant"),
commentNode = document.createComment("some comment"),
textNode = document.createTextNode("some text"),
obj = {};
jQuery.each( [document, attributeNode, commentNode, textNode, obj, "#firstp"], function( i, ele ) {
strictEqual( jQuery(ele).attr("nonexisting"), undefined, "attr works correctly for non existing attributes (bug #7500)." );
});
}); });
if ( !isLocal ) { if ( !isLocal ) {
@ -116,8 +153,8 @@ if ( !isLocal ) {
test("attr(String, Function)", function() { test("attr(String, Function)", function() {
expect(2); expect(2);
equals( jQuery('#text1').attr('value', function() { return this.id ;})[0].value, "text1", "Set value from id" ); equals( jQuery('#text1').attr('value', function() { return this.id; })[0].value, "text1", "Set value from id" );
equals( jQuery('#text1').attr('title', function(i) { return i }).attr('title'), "0", "Set value with an index"); equals( jQuery('#text1').attr('title', function(i) { return i; }).attr('title'), "0", "Set value with an index");
}); });
test("attr(Hash)", function() { test("attr(Hash)", function() {
@ -133,7 +170,7 @@ test("attr(Hash)", function() {
}); });
test("attr(String, Object)", function() { test("attr(String, Object)", function() {
expect(30); expect(29);
var div = jQuery("div").attr("foo", "bar"), var div = jQuery("div").attr("foo", "bar"),
fail = false; fail = false;
@ -153,7 +190,7 @@ test("attr(String, Object)", function() {
jQuery("#name").attr('name', 'something'); jQuery("#name").attr('name', 'something');
equals( jQuery("#name").attr('name'), 'something', 'Set name attribute' ); equals( jQuery("#name").attr('name'), 'something', 'Set name attribute' );
jQuery("#name").attr('name', null); jQuery("#name").attr('name', null);
equals( jQuery("#name").attr('title'), '', 'Remove name attribute' ); equals( jQuery("#name").attr('name'), undefined, 'Remove name attribute' );
jQuery("#check2").attr('checked', true); jQuery("#check2").attr('checked', true);
equals( document.getElementById('check2').checked, true, 'Set checked attribute' ); equals( document.getElementById('check2').checked, true, 'Set checked attribute' );
jQuery("#check2").attr('checked', false); jQuery("#check2").attr('checked', false);
@ -163,28 +200,22 @@ test("attr(String, Object)", function() {
jQuery("#text1").attr('readonly', false); jQuery("#text1").attr('readonly', false);
equals( document.getElementById('text1').readOnly, false, 'Set readonly attribute' ); equals( document.getElementById('text1').readOnly, false, 'Set readonly attribute' );
jQuery("#name").attr('maxlength', '5'); jQuery("#name").attr('maxlength', '5');
equals( document.getElementById('name').maxLength, '5', 'Set maxlength attribute' ); equals( document.getElementById('name').maxLength, 5, 'Set maxlength attribute' );
jQuery("#name").attr('maxLength', '10'); jQuery("#name").attr('maxLength', '10');
equals( document.getElementById('name').maxLength, '10', 'Set maxlength attribute' ); equals( document.getElementById('name').maxLength, 10, 'Set maxlength attribute' );
var $p = jQuery('#firstp').attr('nonexisting', 'foo');
equals( $p.attr('nonexisting'), 'foo', "attr(name, value) works correctly for non existing attributes (bug #7500).");
$p.removeAttr('nonexisting');
var attributeNode = document.createAttribute("irrelevant"), var attributeNode = document.createAttribute("irrelevant"),
commentNode = document.createComment("some comment"), commentNode = document.createComment("some comment"),
textNode = document.createTextNode("some text"), textNode = document.createTextNode("some text");
obj = {};
jQuery.each( [document, obj, "#firstp"], function( i, ele ) {
var $ele = jQuery( ele );
$ele.attr( "nonexisting", "foo" );
equal( $ele.attr("nonexisting"), "foo", "attr(name, value) works correctly for non existing attributes (bug #7500)." );
});
jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) { jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
var $ele = jQuery( ele ); var $ele = jQuery( ele );
$ele.attr( "nonexisting", "foo" ); $ele.attr( "nonexisting", "foo" );
strictEqual( $ele.attr("nonexisting"), undefined, "attr(name, value) works correctly on comment and text nodes (bug #7500)." ); strictEqual( $ele.attr("nonexisting"), undefined, "attr(name, value) works correctly on comment and text nodes (bug #7500)." );
}); });
//cleanup
jQuery.each( [document, "#firstp"], function( i, ele ) {
jQuery( ele ).removeAttr("nonexisting");
});
var table = jQuery('#table').append("<tr><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr>"), var table = jQuery('#table').append("<tr><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr>"),
td = table.find('td:first'); td = table.find('td:first');
@ -193,15 +224,15 @@ test("attr(String, Object)", function() {
td.attr("colspan", "2"); td.attr("colspan", "2");
equals( td[0].colSpan, 2, "Check colspan is correctly set" ); equals( td[0].colSpan, 2, "Check colspan is correctly set" );
table.attr("cellspacing", "2"); table.attr("cellspacing", "2");
equals( table[0].cellSpacing, 2, "Check cellspacing is correctly set" ); equals( table[0].cellSpacing, "2", "Check cellspacing is correctly set" );
// for #1070 // for #1070
jQuery("#name").attr('someAttr', '0'); jQuery("#name").attr('someAttr', '0');
equals( jQuery("#name").attr('someAttr'), '0', 'Set attribute to a string of "0"' ); equals( jQuery("#name").attr('someAttr'), '0', 'Set attribute to a string of "0"' );
jQuery("#name").attr('someAttr', 0); jQuery("#name").attr('someAttr', 0);
equals( jQuery("#name").attr('someAttr'), 0, 'Set attribute to the number 0' ); equals( jQuery("#name").attr('someAttr'), '0', 'Set attribute to the number 0' );
jQuery("#name").attr('someAttr', 1); jQuery("#name").attr('someAttr', 1);
equals( jQuery("#name").attr('someAttr'), 1, 'Set attribute to the number 1' ); equals( jQuery("#name").attr('someAttr'), '1', 'Set attribute to the number 1' );
// using contents will get comments regular, text, and comment nodes // using contents will get comments regular, text, and comment nodes
var j = jQuery("#nonnodes").contents(); var j = jQuery("#nonnodes").contents();
@ -212,6 +243,7 @@ test("attr(String, Object)", function() {
QUnit.reset(); QUnit.reset();
// Type
var type = jQuery("#check2").attr('type'); var type = jQuery("#check2").attr('type');
var thrown = false; var thrown = false;
try { try {
@ -251,6 +283,13 @@ test("attr(String, Object)", function() {
} }
ok( thrown, "Exception thrown when trying to change type property" ); ok( thrown, "Exception thrown when trying to change type property" );
equals( "button", button.attr('type'), "Verify that you can't change the type of a button element" ); equals( "button", button.attr('type'), "Verify that you can't change the type of a button element" );
// Setting attributes on svg elements (bug #3116)
var $svg = jQuery('<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" baseProfile="full" width="3000" height="3000">'
+ '<circle cx="200" cy="200" r="150" />'
+ '</svg>').appendTo('body');
equals( $svg.attr('cx', 100).attr('cx'), "100", "Set attribute on svg element" );
$svg.remove();
}); });
test("attr(jquery_method)", function(){ test("attr(jquery_method)", function(){
@ -356,25 +395,32 @@ test("attr('tabindex', value)", function() {
}); });
test("removeAttr(String)", function() { test("removeAttr(String)", function() {
expect(7); expect(5);
equals( jQuery('#mark').removeAttr( "class" )[0].className, "", "remove class" ); equals( jQuery('#mark').removeAttr( "class" )[0].className, "", "remove class" );
equals( jQuery('#form').removeAttr('id').attr('id'), undefined, 'Remove id' );
equals( jQuery('#foo').attr('style', 'position:absolute;').removeAttr('style').attr('style'), undefined, 'Check removing style attribute' );
equals( jQuery('#form').attr('style', 'position:absolute;').removeAttr('style').attr('style'), undefined, 'Check removing style attribute on a form' );
equals( jQuery('#fx-test-group').attr('height', '3px').removeAttr('height').css('height'), "1px", 'Removing height attribute has no effect on height set with style attribute' );
});
test("removeProp(String)", function() {
expect(6);
var attributeNode = document.createAttribute("irrelevant"), var attributeNode = document.createAttribute("irrelevant"),
commentNode = document.createComment("some comment"), commentNode = document.createComment("some comment"),
textNode = document.createTextNode("some text"), textNode = document.createTextNode("some text"),
obj = {}; obj = {};
//removeAttr only really removes on DOM element nodes handle all other seperatyl
strictEqual( jQuery( "#firstp" ).attr( "nonexisting", "foo" ).removeAttr( "nonexisting" )[0].nonexisting, undefined, "removeAttr works correctly on DOM element nodes" ); strictEqual( jQuery( "#firstp" ).prop( "nonexisting", "foo" ).removeProp( "nonexisting" )[0].nonexisting, undefined, "removeprop works correctly on DOM element nodes" );
jQuery.each( [document, obj], function( i, ele ) { jQuery.each( [document, obj], function( i, ele ) {
var $ele = jQuery( ele ); var $ele = jQuery( ele );
$ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" ); $ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
strictEqual( ele.nonexisting, "", "removeAttr works correctly on non DOM element nodes (bug #7500)." ); strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug #7500)." );
}); });
jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) { jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
$ele = jQuery( ele ); $ele = jQuery( ele );
$ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" ); $ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
strictEqual( ele.nonexisting, undefined, "removeAttr works correctly on non DOM element nodes (bug #7500)." ); strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug #7500)." );
}); });
}); });
@ -604,21 +650,20 @@ test("addClass(Function)", function() {
test("addClass(Function) with incoming value", function() { test("addClass(Function) with incoming value", function() {
expect(45); expect(45);
var div = jQuery("div"), old = div.map(function(){ var div = jQuery("div"), old = div.map(function(){
return jQuery(this).attr("class"); return jQuery(this).attr("class") || "";
}); });
div.addClass(function(i, val) { div.addClass(function(i, val) {
if ( this.id !== "_firebugConsole" ) { if ( this.id !== "_firebugConsole") {
equals( val, old[i], "Make sure the incoming value is correct." ); equals( val, old[i], "Make sure the incoming value is correct." );
return "test"; return "test";
} }
}); });
var pass = true; var pass = true;
for ( var i = 0; i < div.size(); i++ ) { for ( var i = 0; i < div.length; i++ ) {
if ( div.get(i).className.indexOf("test") == -1 ) pass = false; if ( div.get(i).className.indexOf("test") == -1 ) pass = false;
} }
ok( pass, "Add Class" ); ok( pass, "Add Class" );
}); });

View file

@ -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 ) { if ( !isLocal ) {
test("browser", function() { test("browser", function() {
stop(); stop();
@ -622,7 +642,7 @@ test("first()/last()", function() {
}); });
test("map()", function() { test("map()", function() {
expect(2);//expect(6); expect(7);
same( same(
jQuery("#ap").map(function(){ jQuery("#ap").map(function(){
@ -640,32 +660,32 @@ test("map()", function() {
"Single Map" "Single Map"
); );
return;//these haven't been accepted yet
//for #2616 //for #2616
var keys = jQuery.map( {a:1,b:2}, function( v, k ){ var keys = jQuery.map( {a:1,b:2}, function( v, k ){
return k; return k;
}, [ ] ); });
equals( keys.join(""), "ab", "Map the keys from a hash to an array" ); equals( keys.join(""), "ab", "Map the keys from a hash to an array" );
var values = jQuery.map( {a:1,b:2}, function( v, k ){ var values = jQuery.map( {a:1,b:2}, function( v, k ){
return v; return v;
}, [ ] ); });
equals( values.join(""), "12", "Map the values from a hash to an array" ); equals( values.join(""), "12", "Map the values from a hash to an array" );
// object with length prop
var values = jQuery.map( {a:1,b:2, length:3}, function( v, k ){
return v;
});
equals( values.join(""), "123", "Map the values from a hash with a length property to an array" );
var scripts = document.getElementsByTagName("script"); var scripts = document.getElementsByTagName("script");
var mapped = jQuery.map( scripts, function( v, k ){ var mapped = jQuery.map( scripts, function( v, k ){
return v; return v;
}, {length:0} ); });
equals( mapped.length, scripts.length, "Map an array(-like) to a hash" ); equals( mapped.length, scripts.length, "Map an array(-like) to a hash" );
var flat = jQuery.map( Array(4), function( v, k ){ var flat = jQuery.map( Array(4), function( v, k ){
return k % 2 ? k : [k,k,k];//try mixing array and regular returns return k % 2 ? k : [k,k,k];//try mixing array and regular returns
}); });
equals( flat.join(""), "00012223", "try the new flatten technique(#2616)" ); equals( flat.join(""), "00012223", "try the new flatten technique(#2616)" );
}); });
@ -883,7 +903,7 @@ test("jQuery.isEmptyObject", function(){
}); });
test("jQuery.proxy", function(){ test("jQuery.proxy", function(){
expect(4); expect(6);
var test = function(){ equals( this, thisObject, "Make sure that scope is set properly." ); }; var test = function(){ equals( this, thisObject, "Make sure that scope is set properly." ); };
var thisObject = { foo: "bar", method: test }; var thisObject = { foo: "bar", method: test };
@ -897,8 +917,17 @@ test("jQuery.proxy", function(){
// Make sure it doesn't freak out // Make sure it doesn't freak out
equals( jQuery.proxy( null, thisObject ), undefined, "Make sure no function was returned." ); equals( jQuery.proxy( null, thisObject ), undefined, "Make sure no function was returned." );
// Use the string shortcut // Partial application
jQuery.proxy( thisObject, "method" )(); var test2 = function( a ){ equals( a, "pre-applied", "Ensure arguments can be pre-applied." ); };
jQuery.proxy( test2, null, "pre-applied" )();
// Partial application w/ normal arguments
var test3 = function( a, b ){ equals( b, "normal", "Ensure arguments can be pre-applied and passed as usual." ); };
jQuery.proxy( test3, null, "pre-applied" )( "normal" );
// Test old syntax
var test4 = { meth: function( a ){ equals( a, "boom", "Ensure old syntax works." ); } };
jQuery.proxy( test4, "meth" )( "boom" );
}); });
test("jQuery.parseJSON", function(){ test("jQuery.parseJSON", function(){

View file

@ -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();
});

View file

@ -1,153 +1,273 @@
module("deferred", { teardown: moduleTeardown }); module("deferred", { teardown: moduleTeardown });
test("jQuery._Deferred()", function() { jQuery.each( [ "", " - new operator" ], function( _, withNew ) {
expect( 11 ); function createDeferred() {
return withNew ? new jQuery._Deferred() : jQuery._Deferred();
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();
} }
test = ""; test("jQuery._Deferred" + withNew, function() {
deferred = jQuery._Deferred().done( 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() { 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.pipe - filtering (done)", function() {
expect(3);
var defer = jQuery.Deferred(),
piped = defer.pipe(function( a, b ) {
return a * b;
}),
value1,
value2,
value3;
piped.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().pipe(function() {
ok( false, "pipe should not be called on reject" );
});
});
test( "jQuery.Deferred.pipe - filtering (fail)", function() {
expect(3);
var defer = jQuery.Deferred(),
piped = defer.pipe( null, function( a, b ) {
return a * b;
} ),
value1,
value2,
value3;
piped.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().pipe( null, function() {
ok( false, "pipe 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.pipe - deferred (done)", function() {
expect( 10 ); expect(3);
jQuery.Deferred( function( defer ) { var defer = jQuery.Deferred(),
strictEqual( this , defer , "Defer passed as this & first argument" ); piped = defer.pipe(function( a, b ) {
this.resolve( "done" ); return jQuery.Deferred(function( defer ) {
}).then( function( value ) { defer.reject( a * b );
strictEqual( value , "done" , "Passed function executed" ); });
}),
value1,
value2,
value3;
piped.fail(function( result ) {
value3 = result;
}); });
jQuery.Deferred().resolve().then( function() { defer.done(function( a, b ) {
ok( true , "Success on resolve" ); value1 = a;
}, function() { value2 = b;
ok( false , "Error on resolve" );
}); });
jQuery.Deferred().reject().then( function() { defer.resolve( 2, 3 );
ok( false , "Success on reject" );
}, function() {
ok( true , "Error on reject" );
});
( new jQuery.Deferred( function( defer ) { strictEqual( value1, 2, "first resolve value ok" );
strictEqual( this , defer , "Defer passed as this & first argument (new)" ); strictEqual( value2, 3, "second resolve value ok" );
this.resolve( "done" ); strictEqual( value3, 6, "result of filter ok" );
}) ).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" );
}); });
test("jQuery.when()", function() { 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,57 +286,63 @@ 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" );
var cache, i; var cache, i;
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
View file

@ -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();
}); });

View file

@ -975,6 +975,27 @@ test("trigger(eventObject, [data], [fn])", function() {
$parent.unbind().remove(); $parent.unbind().remove();
}); });
test("jQuery.Event({ /* props */ })", function() {
expect(4);
var event = jQuery.Event({ type: "keydown", keyCode: 64 }),
handler = function( event ) {
ok( "keyCode" in event, "Special property 'keyCode' exists" );
equal( event.keyCode, 64, "event.keyCode has explicit value '64'" );
};
// Supports jQuery.Event implementation
equal( event.type, "keydown", "Verify type" );
ok( "keyCode" in event, "Special 'keyCode' property exists" );
jQuery("body").bind( "keydown", handler ).trigger( event );
jQuery("body").unbind( "keydown" );
});
test("jQuery.Event.currentTarget", function(){ test("jQuery.Event.currentTarget", function(){
expect(1); expect(1);
@ -2055,6 +2076,19 @@ test("focusin bubbles", function() {
jQuery( "body" ).unbind( "focusin.focusinBubblesTest" ); jQuery( "body" ).unbind( "focusin.focusinBubblesTest" );
}); });
test("custom events with colons (#3533, #8272)", function() {
expect(1);
var tab = jQuery("<table><tr><td>trigger</td></tr></table>").appendTo("body");
try {
tab.trigger("back:forth");
ok( true, "colon events don't throw" );
} catch ( e ) {
ok( false, "colon events die" );
};
tab.remove();
});
(function(){ (function(){
// This code must be run before DOM ready! // This code must be run before DOM ready!
@ -2138,3 +2172,4 @@ test("event properties", function() {
}).click(); }).click();
}); });
*/ */

View file

@ -1009,7 +1009,7 @@ test("clone()", function() {
}); });
test("clone(form element) (Bug #3879, #6655)", function() { test("clone(form element) (Bug #3879, #6655)", function() {
expect(6); expect(5);
var element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>"); var element = jQuery("<select><option>Foo</option><option selected>Bar</option></select>");
equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" ); equals( element.clone().find("option:selected").val(), element.find("option:selected").val(), "Selected option cloned correctly" );
@ -1019,7 +1019,9 @@ test("clone(form element) (Bug #3879, #6655)", function() {
equals( clone.is(":checked"), element.is(":checked"), "Checked input cloned correctly" ); equals( clone.is(":checked"), element.is(":checked"), "Checked input cloned correctly" );
equals( clone[0].defaultValue, "foo", "Checked input defaultValue cloned correctly" ); equals( clone[0].defaultValue, "foo", "Checked input defaultValue cloned correctly" );
equals( clone[0].defaultChecked, !jQuery.support.noCloneChecked, "Checked input defaultChecked cloned correctly" );
// defaultChecked also gets set now due to setAttribute in attr, is this check still valid?
// equals( clone[0].defaultChecked, !jQuery.support.noCloneChecked, "Checked input defaultChecked cloned correctly" );
element = jQuery("<input type='text' value='foo'>"); element = jQuery("<input type='text' value='foo'>");
clone = element.clone(); clone = element.clone();

View file

@ -13,8 +13,32 @@ test("find(String)", function() {
same( jQuery("#main").find("> #foo > p").get(), q("sndp", "en", "sap"), "find child elements" ); same( jQuery("#main").find("> #foo > p").get(), q("sndp", "en", "sap"), "find child elements" );
}); });
test("is(String)", function() { test("find(node|jQuery object)", function() {
expect(26); expect( 11 );
var $foo = jQuery('#foo'),
$blog = jQuery('.blogTest'),
$first = jQuery('#first'),
$two = $blog.add( $first ),
$fooTwo = $foo.add( $blog );
equals( $foo.find( $blog ).text(), 'Yahoo', 'Find with blog jQuery object' );
equals( $foo.find( $blog[0] ).text(), 'Yahoo', 'Find with blog node' );
equals( $foo.find( $first ).length, 0, '#first is not in #foo' );
equals( $foo.find( $first[0]).length, 0, '#first not in #foo (node)' );
ok( $foo.find( $two ).is('.blogTest'), 'Find returns only nodes within #foo' );
ok( $fooTwo.find( $blog ).is('.blogTest'), 'Blog is part of the collection, but also within foo' );
ok( $fooTwo.find( $blog[0] ).is('.blogTest'), 'Blog is part of the collection, but also within foo(node)' );
equals( $two.find( $foo ).length, 0, 'Foo is not in two elements' );
equals( $two.find( $foo[0] ).length, 0, 'Foo is not in two elements(node)' );
equals( $two.find( $first ).length, 0, 'first is in the collection and not within two' );
equals( $two.find( $first ).length, 0, 'first is in the collection and not within two(node)' );
});
test("is(String|undefined)", function() {
expect(27);
ok( jQuery('#form').is('form'), 'Check for element: A form must be a form' ); ok( jQuery('#form').is('form'), 'Check for element: A form must be a form' );
ok( !jQuery('#form').is('div'), 'Check for element: A form is not a div' ); ok( !jQuery('#form').is('div'), 'Check for element: A form is not a div' );
ok( jQuery('#mark').is('.blog'), 'Check for class: Expected class "blog"' ); ok( jQuery('#mark').is('.blog'), 'Check for class: Expected class "blog"' );
@ -33,10 +57,12 @@ test("is(String)", function() {
ok( !jQuery('#foo').is(':has(ul)'), 'Check for child: Did not expect "ul" element' ); ok( !jQuery('#foo').is(':has(ul)'), 'Check for child: Did not expect "ul" element' );
ok( jQuery('#foo').is(':has(p):has(a):has(code)'), 'Check for childs: Expected "p", "a" and "code" child elements' ); ok( jQuery('#foo').is(':has(p):has(a):has(code)'), 'Check for childs: Expected "p", "a" and "code" child elements' );
ok( !jQuery('#foo').is(':has(p):has(a):has(code):has(ol)'), 'Check for childs: Expected "p", "a" and "code" child elements, but no "ol"' ); ok( !jQuery('#foo').is(':has(p):has(a):has(code):has(ol)'), 'Check for childs: Expected "p", "a" and "code" child elements, but no "ol"' );
ok( !jQuery('#foo').is(0), 'Expected false for an invalid expression - 0' ); ok( !jQuery('#foo').is(0), 'Expected false for an invalid expression - 0' );
ok( !jQuery('#foo').is(null), 'Expected false for an invalid expression - null' ); ok( !jQuery('#foo').is(null), 'Expected false for an invalid expression - null' );
ok( !jQuery('#foo').is(''), 'Expected false for an invalid expression - ""' ); ok( !jQuery('#foo').is(''), 'Expected false for an invalid expression - ""' );
ok( !jQuery('#foo').is(undefined), 'Expected false for an invalid expression - undefined' ); ok( !jQuery('#foo').is(undefined), 'Expected false for an invalid expression - undefined' );
ok( !jQuery('#foo').is({ plain: "object" }), 'Check passing invalid object' );
// test is() with comma-seperated expressions // test is() with comma-seperated expressions
ok( jQuery('#en').is('[lang="en"],[lang="de"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); ok( jQuery('#en').is('[lang="en"],[lang="de"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' );
@ -45,6 +71,36 @@ test("is(String)", function() {
ok( jQuery('#en').is('[lang="de"] , [lang="en"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' ); ok( jQuery('#en').is('[lang="de"] , [lang="en"]'), 'Comma-seperated; Check for lang attribute: Expect en or de' );
}); });
test("is(jQuery)", function() {
expect(24);
ok( jQuery('#form').is( jQuery('form') ), 'Check for element: A form is a form' );
ok( !jQuery('#form').is( jQuery('div') ), 'Check for element: A form is not a div' );
ok( jQuery('#mark').is( jQuery('.blog') ), 'Check for class: Expected class "blog"' );
ok( !jQuery('#mark').is( jQuery('.link') ), 'Check for class: Did not expect class "link"' );
ok( jQuery('#simon').is( jQuery('.blog.link') ), 'Check for multiple classes: Expected classes "blog" and "link"' );
ok( !jQuery('#simon').is( jQuery('.blogTest') ), 'Check for multiple classes: Expected classes "blog" and "link", but not "blogTest"' );
ok( jQuery('#en').is( jQuery('[lang="en"]') ), 'Check for attribute: Expected attribute lang to be "en"' );
ok( !jQuery('#en').is( jQuery('[lang="de"]') ), 'Check for attribute: Expected attribute lang to be "en", not "de"' );
ok( jQuery('#text1').is( jQuery('[type="text"]') ), 'Check for attribute: Expected attribute type to be "text"' );
ok( !jQuery('#text1').is( jQuery('[type="radio"]') ), 'Check for attribute: Expected attribute type to be "text", not "radio"' );
ok( jQuery('#text2').is( jQuery(':disabled') ), 'Check for pseudoclass: Expected to be disabled' );
ok( !jQuery('#text1').is( jQuery(':disabled') ), 'Check for pseudoclass: Expected not disabled' );
ok( jQuery('#radio2').is( jQuery(':checked') ), 'Check for pseudoclass: Expected to be checked' );
ok( !jQuery('#radio1').is( jQuery(':checked') ), 'Check for pseudoclass: Expected not checked' );
ok( jQuery('#foo').is( jQuery(':has(p)') ), 'Check for child: Expected a child "p" element' );
ok( !jQuery('#foo').is( jQuery(':has(ul)') ), 'Check for child: Did not expect "ul" element' );
ok( jQuery('#foo').is( jQuery(':has(p):has(a):has(code)') ), 'Check for childs: Expected "p", "a" and "code" child elements' );
ok( !jQuery('#foo').is( jQuery(':has(p):has(a):has(code):has(ol)') ), 'Check for childs: Expected "p", "a" and "code" child elements, but no "ol"' );
// Some raw elements
ok( jQuery('#form').is( jQuery('form')[0] ), 'Check for element: A form is a form' );
ok( !jQuery('#form').is( jQuery('div')[0] ), 'Check for element: A form is not a div' );
ok( jQuery('#mark').is( jQuery('.blog')[0] ), 'Check for class: Expected class "blog"' );
ok( !jQuery('#mark').is( jQuery('.link')[0] ), 'Check for class: Did not expect class "link"' );
ok( jQuery('#simon').is( jQuery('.blog.link')[0] ), 'Check for multiple classes: Expected classes "blog" and "link"' );
ok( !jQuery('#simon').is( jQuery('.blogTest')[0] ), 'Check for multiple classes: Expected classes "blog" and "link", but not "blogTest"' );
});
test("index()", function() { test("index()", function() {
expect(1); expect(1);
@ -82,12 +138,17 @@ test("index(Object|String|undefined)", function() {
equals( jQuery('#radio2').index('#form :text') , -1, "Check for index not found within a selector" ); equals( jQuery('#radio2').index('#form :text') , -1, "Check for index not found within a selector" );
}); });
test("filter(Selector)", function() { test("filter(Selector|undefined)", function() {
expect(5); expect(9);
same( jQuery("#form input").filter(":checked").get(), q("radio2", "check1"), "filter(String)" ); same( jQuery("#form input").filter(":checked").get(), q("radio2", "check1"), "filter(String)" );
same( jQuery("p").filter("#ap, #sndp").get(), q("ap", "sndp"), "filter('String, String')" ); same( jQuery("p").filter("#ap, #sndp").get(), q("ap", "sndp"), "filter('String, String')" );
same( jQuery("p").filter("#ap,#sndp").get(), q("ap", "sndp"), "filter('String,String')" ); same( jQuery("p").filter("#ap,#sndp").get(), q("ap", "sndp"), "filter('String,String')" );
same( jQuery('p').filter(null).get(), [], "filter(null) should return an empty jQuery object");
same( jQuery('p').filter(undefined).get(), [], "filter(undefined) should return an empty jQuery object");
same( jQuery('p').filter(0).get(), [], "filter(0) should return an empty jQuery object");
same( jQuery('p').filter('').get(), [], "filter('') should return an empty jQuery object");
// using contents will get comments regular, text, and comment nodes // using contents will get comments regular, text, and comment nodes
var j = jQuery("#nonnodes").contents(); var j = jQuery("#nonnodes").contents();
equals( j.filter("span").length, 1, "Check node,textnode,comment to filter the one span" ); equals( j.filter("span").length, 1, "Check node,textnode,comment to filter the one span" );
@ -124,7 +185,7 @@ test("filter(jQuery)", function() {
}) })
test("closest()", function() { test("closest()", function() {
expect(11); expect(13);
same( jQuery("body").closest("body").get(), q("body"), "closest(body)" ); same( jQuery("body").closest("body").get(), q("body"), "closest(body)" );
same( jQuery("body").closest("html").get(), q("html"), "closest(html)" ); same( jQuery("body").closest("html").get(), q("html"), "closest(html)" );
same( jQuery("body").closest("div").get(), [], "closest(div)" ); same( jQuery("body").closest("div").get(), [], "closest(div)" );
@ -144,6 +205,10 @@ test("closest()", function() {
// Test on disconnected node // Test on disconnected node
equals( jQuery("<div><p></p></div>").find("p").closest("table").length, 0, "Make sure disconnected closest work." ); equals( jQuery("<div><p></p></div>").find("p").closest("table").length, 0, "Make sure disconnected closest work." );
// Bug #7369
equals( jQuery('<div foo="bar"></div>').closest('[foo]').length, 1, "Disconnected nodes with attribute selector" );
equals( jQuery('<div>text</div>').closest('[lang]').length, 0, "Disconnected nodes with text and non-existent attribute selector" );
}); });
test("closest(Array)", function() { test("closest(Array)", function() {
@ -158,8 +223,29 @@ test("closest(Array)", function() {
same( jQuery("body").closest(["span","html"]), [{selector:"html", elem:document.documentElement, level:2}], "closest([body, html])" ); same( jQuery("body").closest(["span","html"]), [{selector:"html", elem:document.documentElement, level:2}], "closest([body, html])" );
}); });
<<<<<<< HEAD
test("not(Selector|undefined)", function() {
expect(11);
=======
test("closest(jQuery)", function() {
expect(8);
var $child = jQuery("#nothiddendivchild"),
$parent = jQuery("#nothiddendiv"),
$main = jQuery("#main"),
$body = jQuery("body");
ok( $child.closest( $parent ).is('#nothiddendiv'), "closest( jQuery('#nothiddendiv') )" );
ok( $child.closest( $parent[0] ).is('#nothiddendiv'), "closest( jQuery('#nothiddendiv') ) :: node" );
ok( $child.closest( $child ).is('#nothiddendivchild'), "child is included" );
ok( $child.closest( $child[0] ).is('#nothiddendivchild'), "child is included :: node" );
equals( $child.closest( document.createElement('div') ).length, 0, "created element is not related" );
equals( $child.closest( $main ).length, 0, "Main not a parent of child" );
equals( $child.closest( $main[0] ).length, 0, "Main not a parent of child :: node" );
ok( $child.closest( $body.add($parent) ).is('#nothiddendiv'), "Closest ancestor retrieved." );
});
test("not(Selector)", function() { test("not(Selector)", function() {
expect(7); expect(7);
>>>>>>> 1a167767305202797cf4c839eb64bd7adfb00182
equals( jQuery("#main > p#ap > a").not("#google").length, 2, "not('selector')" ); equals( jQuery("#main > p#ap > a").not("#google").length, 2, "not('selector')" );
same( jQuery("p").not(".result").get(), q("firstp", "ap", "sndp", "en", "sap", "first"), "not('.class')" ); same( jQuery("p").not(".result").get(), q("firstp", "ap", "sndp", "en", "sap", "first"), "not('.class')" );
same( jQuery("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" ); same( jQuery("p").not("#ap, #sndp, .result").get(), q("firstp", "en", "sap", "first"), "not('selector, selector')" );
@ -168,6 +254,12 @@ test("not(Selector)", function() {
same( jQuery('#ap *').not('code').get(), q("google", "groups", "anchor1", "mark"), "not('tag selector')" ); same( jQuery('#ap *').not('code').get(), q("google", "groups", "anchor1", "mark"), "not('tag selector')" );
same( jQuery('#ap *').not('code, #mark').get(), q("google", "groups", "anchor1"), "not('tag, ID selector')" ); same( jQuery('#ap *').not('code, #mark').get(), q("google", "groups", "anchor1"), "not('tag, ID selector')" );
same( jQuery('#ap *').not('#mark, code').get(), q("google", "groups", "anchor1"), "not('ID, tag selector')"); same( jQuery('#ap *').not('#mark, code').get(), q("google", "groups", "anchor1"), "not('ID, tag selector')");
var all = jQuery('p').get();
same( jQuery('p').not(null).get(), all, "not(null) should have no effect");
same( jQuery('p').not(undefined).get(), all, "not(undefined) should have no effect");
same( jQuery('p').not(0).get(), all, "not(0) should have no effect");
same( jQuery('p').not('').get(), all, "not('') should have no effect");
}); });
test("not(Element)", function() { test("not(Element)", function() {