aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjaubourg <j@ubourg.net>2011-04-11 13:41:17 +0200
committerjaubourg <j@ubourg.net>2011-04-11 13:41:17 +0200
commit4c3aba9a15c936696ad2e799f7e372bf2aeb38a5 (patch)
treebe25f30c1eb60aa2b87412b51eab7745b2005760
parent3411d47a6a952e283864d2401438a6764d925b74 (diff)
parent56ffad2dad138293c132e6ad353111bd2d1f1239 (diff)
downloadjquery-4c3aba9a15c936696ad2e799f7e372bf2aeb38a5.tar.gz
jquery-4c3aba9a15c936696ad2e799f7e372bf2aeb38a5.zip
Merge branch 'master' of github.com:jquery/jquery
-rw-r--r--README.md83
-rw-r--r--src/attributes.js508
-rw-r--r--src/core.js97
-rw-r--r--src/data.js12
-rw-r--r--src/effects.js23
-rw-r--r--src/event.js62
-rw-r--r--src/manipulation.js5
m---------src/sizzle0
-rw-r--r--src/support.js12
-rw-r--r--src/traversing.js48
-rw-r--r--test/index.html4
-rw-r--r--test/unit/attributes.js229
-rw-r--r--test/unit/core.js35
-rw-r--r--test/unit/data.js19
-rw-r--r--test/unit/event.js22
-rw-r--r--test/unit/manipulation.js6
-rw-r--r--test/unit/traversing.js104
17 files changed, 899 insertions, 370 deletions
diff --git a/README.md b/README.md
index d56576c81..17b38de6c 100644
--- a/README.md
+++ b/README.md
@@ -56,6 +56,89 @@ Sometimes, the various git repositories get into an inconsistent state where bui
(usually this results in the jquery.js or jquery.min.js being 0 bytes). If this happens, run `make clean`, then
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?
----------
diff --git a/src/attributes.js b/src/attributes.js
index 599721055..c34cd6193 100644
--- a/src/attributes.js
+++ b/src/attributes.js
@@ -3,44 +3,41 @@
var rclass = /[\n\t\r]/g,
rspaces = /\s+/,
rreturn = /\r/g,
- rspecialurl = /^(?:href|src|style)$/,
rtype = /^(?:button|input)$/i,
rfocusable = /^(?:button|input|object|select|textarea)$/i,
rclickable = /^a(?:rea)?$/i,
- rradiocheck = /^(?:radio|checkbox)$/i;
-
-jQuery.props = {
- "for": "htmlFor",
- "class": "className",
- readonly: "readOnly",
- maxlength: "maxLength",
- cellspacing: "cellSpacing",
- rowspan: "rowSpan",
- colspan: "colSpan",
- tabindex: "tabIndex",
- usemap: "useMap",
- frameborder: "frameBorder"
-};
+ formHook;
jQuery.fn.extend({
attr: function( name, value ) {
return jQuery.access( this, name, value, true, jQuery.attr );
},
- removeAttr: function( name, fn ) {
- return this.each(function(){
- jQuery.attr( this, name, "" );
- if ( this.nodeType === 1 ) {
- this.removeAttribute( name );
- }
+ removeAttr: function( name ) {
+ return this.each(function() {
+ jQuery.removeAttr( this, 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 ) {
- if ( jQuery.isFunction(value) ) {
+ if ( jQuery.isFunction( value ) ) {
return this.each(function(i) {
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 ) {
+ var hooks, ret,
+ elem = this[0];
+
if ( !arguments.length ) {
- var elem = this[0];
-
if ( elem ) {
- if ( jQuery.nodeName( elem, "option" ) ) {
- // 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;
- }
-
- // 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" )) ) {
+ hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ];
- // 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;
+ if ( hooks && "get" in hooks && (ret = hooks.get( elem )) !== undefined ) {
+ return ret;
}
- // 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 undefined;
}
- var isFunction = jQuery.isFunction(value);
+ var isFunction = jQuery.isFunction( value );
- return this.each(function(i) {
- var self = jQuery(this), val = value;
+ return this.each(function( i ) {
+ var self = jQuery(this), val;
if ( this.nodeType !== 1 ) {
return;
}
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
@@ -237,34 +188,88 @@ jQuery.fn.extend({
val = "";
} else if ( typeof val === "number" ) {
val += "";
- } else if ( jQuery.isArray(val) ) {
- val = jQuery.map(val, function (value) {
+ } else if ( jQuery.isArray( val ) ) {
+ val = jQuery.map(val, function ( value ) {
return value == null ? "" : value + "";
});
}
- if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) {
- this.checked = jQuery.inArray( self.val(), val ) >= 0;
+ hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ];
+
+ // If set returns undefined, fall back to normal setting
+ if ( !hooks || ("set" in hooks && hooks.set( this, val ) === undefined) ) {
+ this.value = val;
+ }
+ });
+ }
+});
+
+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;
+ },
- } else if ( jQuery.nodeName( this, "select" ) ) {
- var values = jQuery.makeArray(val);
+ set: function( elem, value ) {
+ var values = jQuery.makeArray( value );
- jQuery( "option", this ).each(function() {
+ jQuery(elem).find("option").each(function() {
this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0;
});
if ( !values.length ) {
- this.selectedIndex = -1;
+ elem.selectedIndex = -1;
}
-
- } else {
- this.value = val;
+ return values;
}
- });
- }
-});
+ }
+ },
-jQuery.extend({
attrFn: {
val: true,
css: true,
@@ -275,115 +280,266 @@ jQuery.extend({
height: true,
offset: true
},
-
+
+ attrFix: {
+ // Always normalize to ensure hook usage
+ tabindex: "tabIndex",
+ readonly: "readOnly"
+ },
+
attr: function( elem, name, value, pass ) {
+ var nType = elem.nodeType;
+
// 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;
}
if ( pass && name in jQuery.attrFn ) {
- return jQuery(elem)[name](value);
+ return jQuery( elem )[ name ]( value );
}
+
+ var ret, hooks,
+ notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
+
+ // Normalize the name if needed
+ name = notxml && jQuery.attrFix[ name ] || name;
- var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
- // Whether we are setting (or getting)
- set = value !== undefined;
+ // Get the appropriate hook, or the formHook
+ // if getSetAttribute is not supported and we have form objects in IE6/7
+ hooks = jQuery.attrHooks[ name ] || ( elem.nodeName === "FORM" && formHook );
- // Try to normalize/fix the name
- name = notxml && jQuery.props[ name ] || name;
+ if ( value !== undefined ) {
- // Only do all the following if this is a node (faster for style)
- if ( elem.nodeType === 1 ) {
- // These attributes require special treatment
- var special = rspecialurl.test( name );
-
- // Safari mis-reports the default selected property of an option
- // 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 ( parent.parentNode ) {
- parent.parentNode.selectedIndex;
- }
- }
+ if ( value === null ) {
+ jQuery.removeAttr( elem, name );
+ 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
- // '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" );
- }
+ } else {
- if ( value === null ) {
- if ( elem.nodeType === 1 ) {
- elem.removeAttribute( name );
- }
+ if ( hooks && "get" in hooks && notxml ) {
+ return hooks.get( elem, name );
- } else {
- elem[ name ] = value;
- }
- }
+ } else {
- // browsers index elements by id/name on forms, give priority to attributes.
- if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
- return elem.getAttributeNode( name ).nodeValue;
- }
+ 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" );
+ }
+ }
+ },
+ tabIndex: {
+ get: function( elem ) {
// 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/
- if ( name === "tabIndex" ) {
- var attributeNode = elem.getAttributeNode( "tabIndex" );
-
- return attributeNode && attributeNode.specified ?
- attributeNode.value :
- rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
- 0 :
- undefined;
- }
+ var attributeNode = elem.getAttributeNode("tabIndex");
+ return attributeNode && attributeNode.specified ?
+ parseInt( attributeNode.value, 10 ) :
+ rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
+ 0 :
+ 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 ];
}
+ }
+ },
+
+ propHooks: {}
+});
- if ( !jQuery.support.style && notxml && name === "style" ) {
- 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 ) {
- // convert the value to a string (all browsers do this but IE) see #1070
- elem.setAttribute( name, "" + value );
+ });
+ });
+}
+
+// Remove certain attrs if set to false
+jQuery.each([ "selected", "checked", "readOnly", "disabled" ], function( i, name ) {
+ 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;
+// 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;
}
-
- 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;
+ });
+ });
+}
+
+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);
}
- // Handle everything which isn't a DOM element node
- if ( set ) {
- elem[ name ] = value;
+ };
+}
+
+// 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;
+ }
+ }
}
- return elem[ name ];
- }
+ });
+}
+
+// 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 );
diff --git a/src/core.js b/src/core.js
index 3331969a3..d3641365b 100644
--- a/src/core.js
+++ b/src/core.js
@@ -88,7 +88,7 @@ jQuery.fn = jQuery.prototype = {
if ( selector === "body" && !context && document.body ) {
this.context = document;
this[0] = document.body;
- this.selector = "body";
+ this.selector = selector;
this.length = 1;
return this;
}
@@ -658,8 +658,9 @@ jQuery.extend({
},
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++ ) {
@@ -709,15 +710,30 @@ jQuery.extend({
// arg is for internal usage only
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
- // new value (or values).
- for ( var i = 0, length = elems.length; i < length; i++ ) {
- value = callback( elems[ i ], i, arg );
+ if ( isArray ) {
+ for ( ; i < length; i++ ) {
+ value = callback( elems[ i ], i, arg );
+
+ if ( value != null ) {
+ ret[ ret.length ] = value;
+ }
+ }
- if ( value != null ) {
- 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;
+ }
}
}
@@ -728,31 +744,52 @@ jQuery.extend({
// A global GUID counter for objects
guid: 1,
- proxy: function( fn, proxy, thisObject ) {
- if ( arguments.length === 2 ) {
- if ( typeof proxy === "string" ) {
- thisObject = fn;
- fn = thisObject[ proxy ];
- proxy = undefined;
+ // Bind a function to a context, optionally partially applying any
+ // arguments.
+ proxy: function( fn, context ) {
+ var args, proxy;
- } else if ( proxy && !jQuery.isFunction( proxy ) ) {
- thisObject = proxy;
- proxy = undefined;
- }
+ // XXX BACKCOMPAT: Support old string method.
+ if ( typeof context === "string" ) {
+ fn = fn[ context ];
+ context = arguments[0];
}
- if ( !proxy && fn ) {
- proxy = function() {
- return fn.apply( thisObject || this, arguments );
- };
+ // 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;
}
- // 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++;
+ 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 );
+ };
+ }
}
- // So proxy can be declared as an argument
+ // Set the guid of unique handler to the same of original handler, so it can be removed
+ proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++;
+
return proxy;
},
@@ -843,12 +880,6 @@ if ( jQuery.browser.webkit ) {
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
if ( rnotwhite.test( "\xA0" ) ) {
trimLeft = /^[\s\xA0]+/;
diff --git a/src/data.js b/src/data.js
index 2d53a7104..c2fd558f0 100644
--- a/src/data.js
+++ b/src/data.js
@@ -1,6 +1,7 @@
(function( jQuery ) {
-var rbrace = /^(?:\{.*\}|\[.*\])$/;
+var rbrace = /^(?:\{.*\}|\[.*\])$/,
+ rmultiDash = /([a-z])([A-Z])/g;
jQuery.extend({
cache: {},
@@ -223,12 +224,13 @@ jQuery.fn.extend({
data = jQuery.data( this[0] );
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++ ) {
name = attr[i].name;
if ( name.indexOf( "data-" ) === 0 ) {
- name = name.substr( 5 );
+ name = jQuery.camelCase( name.substring(5) );
+
dataAttr( this[0], name, data[ name ] );
}
}
@@ -282,7 +284,9 @@ function dataAttr( elem, key, data ) {
// If nothing was found internally, try to fetch any
// data from the HTML5 data-* attribute
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" ) {
try {
diff --git a/src/effects.js b/src/effects.js
index d6eff7b32..7aec83009 100644
--- a/src/effects.js
+++ b/src/effects.js
@@ -12,7 +12,10 @@ var elemdisplay = {},
// opacity animations
[ "opacity" ]
],
- fxNow;
+ fxNow,
+ requestAnimationFrame = window.webkitRequestAnimationFrame ||
+ window.mozRequestAnimationFrame ||
+ window.oRequestAnimationFrame;
function clearFxNow() {
fxNow = undefined;
@@ -368,7 +371,8 @@ jQuery.fx.prototype = {
// Start an animation from one number to another
custom: function( from, to, unit ) {
var self = this,
- fx = jQuery.fx;
+ fx = jQuery.fx,
+ raf;
this.startTime = fxNow || createFxNow();
this.start = from;
@@ -384,7 +388,20 @@ jQuery.fx.prototype = {
t.elem = this.elem;
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 );
+ }
}
},
diff --git a/src/event.js b/src/event.js
index 788bb20eb..ac0da6b7e 100644
--- a/src/event.js
+++ b/src/event.js
@@ -1,6 +1,7 @@
(function( jQuery ) {
-var rnamespaces = /\.(.*)$/,
+var hasOwn = Object.prototype.hasOwnProperty,
+ rnamespaces = /\.(.*)$/,
rformElems = /^(?:textarea|input|select)$/i,
rperiod = /\./g,
rspace = / /g,
@@ -563,7 +564,15 @@ jQuery.Event = function( src ) {
// Event object
if ( src && src.type ) {
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
// by a handler lower down the tree; reflect the correct value.
@@ -852,10 +861,10 @@ function trigger( type, elem, args ) {
// Create "bubbling" focus and blur events
if ( !jQuery.support.focusinBubbles ) {
jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) {
-
+
// Attach a single capturing handler while someone wants focusin/focusout
var attaches = 0;
-
+
jQuery.event.special[ fix ] = {
setup: function() {
if ( attaches++ === 0 ) {
@@ -885,6 +894,8 @@ if ( !jQuery.support.focusinBubbles ) {
jQuery.each(["bind", "one"], function( i, name ) {
jQuery.fn[ name ] = function( type, data, fn ) {
+ var handler;
+
// Handle object literals
if ( typeof type === "object" ) {
for ( var key in type ) {
@@ -898,10 +909,15 @@ jQuery.each(["bind", "one"], function( i, name ) {
data = undefined;
}
- var handler = name === "one" ? jQuery.proxy( fn, function( event ) {
- jQuery( this ).unbind( event, handler );
- return fn.apply( this, arguments );
- }) : fn;
+ if ( name === "one" ) {
+ handler = function( event ) {
+ jQuery( this ).unbind( event, handler );
+ return fn.apply( this, arguments );
+ };
+ handler.guid = fn.guid || jQuery.guid++;
+ } else {
+ handler = fn;
+ }
if ( type === "unload" && name !== "one" ) {
this.one( type, data, fn );
@@ -965,24 +981,27 @@ jQuery.fn.extend({
toggle: function( fn ) {
// Save reference to arguments for access in closure
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
+ toggler.guid = guid;
while ( i < args.length ) {
- jQuery.proxy( fn, args[ i++ ] );
+ args[ i++ ].guid = guid;
}
- return this.click( jQuery.proxy( fn, 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;
- }));
+ return this.click( toggler );
},
hover: function( fnOver, fnOut ) {
@@ -1168,3 +1187,4 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl
});
})( jQuery );
+
diff --git a/src/manipulation.js b/src/manipulation.js
index 27f81cc24..758cdbae0 100644
--- a/src/manipulation.js
+++ b/src/manipulation.js
@@ -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
if ( dest.nodeType !== 1 ) {
return;
@@ -549,7 +549,8 @@ jQuery.extend({
// Return the cloned set
return clone;
-},
+ },
+
clean: function( elems, context, fragment, scripts ) {
context = context || document;
diff --git a/src/sizzle b/src/sizzle
-Subproject f12b9309269ba7e705a99efe099f86ed1fe98d5
+Subproject c50b0cddec48494ba882606d03e14cce647d243
diff --git a/src/support.js b/src/support.js
index 50ae6dfd7..34960505a 100644
--- a/src/support.js
+++ b/src/support.js
@@ -19,7 +19,8 @@ jQuery.support = (function() {
isSupported;
// Preliminary tests
- div.innerHTML = " <link/><table></table><a href='/a' style='color:red;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
+ div.setAttribute("className", "t");
+ div.innerHTML = " <link/><table></table><a href='/a' style='top:1px;float:left;opacity:.55;'>a</a><input type='checkbox'/>";
all = div.getElementsByTagName( "*" );
a = div.getElementsByTagName( "a" )[ 0 ];
@@ -48,7 +49,7 @@ jQuery.support = (function() {
// Get the style information from getAttribute
// (IE uses .cssText instead)
- style: /red/.test( a.getAttribute("style") ),
+ style: /top/.test( a.getAttribute("style") ),
// Make sure that URLs aren't manipulated
// (IE normalizes it by default)
@@ -71,6 +72,13 @@ jQuery.support = (function() {
// 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)
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
submitBubbles: true,
diff --git a/src/traversing.js b/src/traversing.js
index fe2e33d88..fb5946bba 100644
--- a/src/traversing.js
+++ b/src/traversing.js
@@ -17,17 +17,30 @@ var runtil = /Until$/,
jQuery.fn.extend({
find: function( selector ) {
+ var self = this,
+ i, l;
+
+ 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 = 0;
+ length, n, r;
- for ( var i = 0, l = this.length; i < l; i++ ) {
+ for ( i = 0, l = this.length; i < l; i++ ) {
length = ret.length;
jQuery.find( selector, this[i], ret );
if ( i > 0 ) {
// Make sure that the results are unique
- for ( var n = length; n < ret.length; n++ ) {
- for ( var r = 0; r < length; r++ ) {
+ for ( n = length; n < ret.length; n++ ) {
+ for ( r = 0; r < length; r++ ) {
if ( ret[r] === ret[n] ) {
ret.splice(n--, 1);
break;
@@ -60,12 +73,15 @@ jQuery.fn.extend({
},
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 ) {
var ret = [], i, l, cur = this[0];
-
+
+ // Array
if ( jQuery.isArray( selectors ) ) {
var match, selector,
matches = {},
@@ -75,8 +91,8 @@ jQuery.fn.extend({
for ( i = 0, l = selectors.length; i < l; i++ ) {
selector = selectors[i];
- if ( !matches[selector] ) {
- matches[selector] = jQuery.expr.match.POS.test( selector ) ?
+ if ( !matches[ selector ] ) {
+ matches[ selector ] = POS.test( selector ) ?
jQuery( selector, context || this.context ) :
selector;
}
@@ -84,9 +100,9 @@ jQuery.fn.extend({
while ( cur && cur.ownerDocument && cur !== context ) {
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 });
}
}
@@ -99,8 +115,10 @@ jQuery.fn.extend({
return ret;
}
- var pos = POS.test( selectors ) ?
- jQuery( selectors, context || this.context ) : null;
+ // String
+ var pos = POS.test( selectors ) || typeof selectors !== "string" ?
+ jQuery( selectors, context || this.context ) :
+ 0;
for ( i = 0, l = this.length; i < l; i++ ) {
cur = this[i];
@@ -112,14 +130,14 @@ jQuery.fn.extend({
} else {
cur = cur.parentNode;
- if ( !cur || !cur.ownerDocument || cur === context ) {
+ if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) {
break;
}
}
}
}
- ret = ret.length > 1 ? jQuery.unique(ret) : ret;
+ ret = ret.length > 1 ? jQuery.unique( ret ) : ret;
return this.pushStack( ret, "closest", selectors );
},
@@ -286,7 +304,7 @@ function winnow( elements, qualifier, keep ) {
return retVal === keep;
});
- } else if ( qualifier.nodeType ) {
+ } else if ( qualifier && qualifier.nodeType ) {
return jQuery.grep(elements, function( elem, i ) {
return (elem === qualifier) === keep;
});
diff --git a/test/index.html b/test/index.html
index c7c2ae55d..a10655089 100644
--- a/test/index.html
+++ b/test/index.html
@@ -203,6 +203,10 @@ Z</textarea>
<select name="D4" disabled="disabled">
<option selected="selected" value="NO">NO</option>
</select>
+ <input id="list-test" type="text" />
+ <datalist id="datalist">
+ <option value="option"></option>
+ </datalist>
</form>
<div id="moretests">
<form>
diff --git a/test/unit/attributes.js b/test/unit/attributes.js
index 8cf47bed6..f3f0bab2b 100644
--- a/test/unit/attributes.js
+++ b/test/unit/attributes.js
@@ -3,38 +3,81 @@ module("attributes", { teardown: moduleTeardown });
var bareObj = function(value) { return value; };
var functionReturningObj = function(value) { return (function() { return value; }); };
-test("jQuery.props: itegrity test", function() {
-
- expect(1);
-
- // This must be maintained and equal jQuery.props
- // Ensure that accidental or erroneous property
- // overwrites don't occur
- // This is simply for better code coverage and future proofing.
- var propsShouldBe = {
- "for": "htmlFor",
- "class": "className",
- readonly: "readOnly",
- maxlength: "maxLength",
- cellspacing: "cellSpacing",
- rowspan: "rowSpan",
- colspan: "colSpan",
- tabindex: "tabIndex",
- usemap: "useMap",
- frameborder: "frameBorder"
- };
-
- same(propsShouldBe, jQuery.props, "jQuery.props passes integrity check");
+test("jQuery.attrFix integrity test", function() {
+ expect(1);
+
+ // This must be maintained and equal jQuery.attrFix when appropriate
+ // Ensure that accidental or erroneous property
+ // overwrites don't occur
+ // This is simply for better code coverage and future proofing.
+ var propsShouldBe;
+ if ( !jQuery.support.getSetAttribute ) {
+ propsShouldBe = {
+ tabindex: "tabIndex",
+ readonly: "readOnly",
+ "for": "htmlFor",
+ "class": "className",
+ maxlength: "maxLength",
+ cellspacing: "cellSpacing",
+ rowspan: "rowSpan",
+ colspan: "colSpan",
+ usemap: "useMap",
+ frameborder: "frameBorder"
+ };
+ } else {
+ propsShouldBe = {
+ tabindex: "tabIndex",
+ readonly: "readOnly"
+ };
+ }
+
+ same(propsShouldBe, jQuery.attrFix, "jQuery.attrFix passes integrity check");
});
-test("attr(String)", function() {
- expect(37);
+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");
+});
- // This one sometimes fails randomly ?!
- equals( jQuery('#text1').attr('value'), "Test", 'Check for value attribute' );
+test("attr(String)", function() {
+ expect(32);
- 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('#radio1').attr('type'), "radio", '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('#text1').attr('name'), "action", 'Check for name attribute' );
ok( jQuery('#form').attr('action').indexOf("formaction") >= 0, 'Check for action attribute' );
- // Temporarily disabled. See: #4299
- // ok( jQuery('#form').attr('action','newformaction').attr('action').indexOf("newformaction") >= 0, 'Check that action attribute was changed' );
+ equals( jQuery('#form').attr('blah', 'blah').attr('blah'), 'blah', 'Set non-existant attribute on a form' );
+ 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('#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
jQuery('<a/>').attr({ 'id': 'tAnchor5', 'href': '#5' }).appendTo('#main');
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]
var body = document.body, $body = jQuery(body);
- ok( $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' );
+ strictEqual( $body.attr('foo'), undefined, 'Make sure that a non existent attribute returns undefined' );
body.setAttribute('foo', 'baz');
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');
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
- var select = document.createElement("select"), optgroup = document.createElement("optgroup"), option = document.createElement("option");
- optgroup.appendChild( option );
- select.appendChild( optgroup );
+ 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');
+ equals( $img.attr('width'), "215", "Retrieve width attribute an an element with display:none." );
+ 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().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 ) {
@@ -116,8 +153,8 @@ if ( !isLocal ) {
test("attr(String, Function)", function() {
expect(2);
- 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('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");
});
test("attr(Hash)", function() {
@@ -133,7 +170,7 @@ test("attr(Hash)", function() {
});
test("attr(String, Object)", function() {
- expect(30);
+ expect(29);
var div = jQuery("div").attr("foo", "bar"),
fail = false;
@@ -153,7 +190,7 @@ test("attr(String, Object)", function() {
jQuery("#name").attr('name', 'something');
equals( jQuery("#name").attr('name'), 'something', 'Set name attribute' );
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);
equals( document.getElementById('check2').checked, true, 'Set checked attribute' );
jQuery("#check2").attr('checked', false);
@@ -163,28 +200,22 @@ test("attr(String, Object)", function() {
jQuery("#text1").attr('readonly', false);
equals( document.getElementById('text1').readOnly, false, 'Set readonly attribute' );
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');
- 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"),
commentNode = document.createComment("some comment"),
- 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)." );
- });
+ textNode = document.createTextNode("some text");
+
jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
var $ele = jQuery( ele );
$ele.attr( "nonexisting", "foo" );
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>"),
td = table.find('td:first');
@@ -193,15 +224,15 @@ test("attr(String, Object)", function() {
td.attr("colspan", "2");
equals( td[0].colSpan, 2, "Check colspan is correctly set" );
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
jQuery("#name").attr('someAttr', '0');
equals( jQuery("#name").attr('someAttr'), '0', 'Set attribute to a string of "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);
- 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
var j = jQuery("#nonnodes").contents();
@@ -211,7 +242,8 @@ test("attr(String, Object)", function() {
j.removeAttr("name");
QUnit.reset();
-
+
+ // Type
var type = jQuery("#check2").attr('type');
var thrown = false;
try {
@@ -251,6 +283,13 @@ test("attr(String, Object)", function() {
}
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" );
+
+ // 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(){
@@ -356,25 +395,32 @@ test("attr('tabindex', value)", function() {
});
test("removeAttr(String)", function() {
- expect(7);
+ expect(5);
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"),
commentNode = document.createComment("some comment"),
textNode = document.createTextNode("some text"),
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 ) {
var $ele = jQuery( ele );
- $ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" );
- strictEqual( ele.nonexisting, "", "removeAttr works correctly on non DOM element nodes (bug #7500)." );
+ $ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
+ strictEqual( ele.nonexisting, undefined, "removeProp works correctly on non DOM element nodes (bug #7500)." );
});
jQuery.each( [commentNode, textNode, attributeNode], function( i, ele ) {
$ele = jQuery( ele );
- $ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" );
- strictEqual( ele.nonexisting, undefined, "removeAttr works correctly on non DOM element nodes (bug #7500)." );
+ $ele.prop( "nonexisting", "foo" ).removeProp( "nonexisting" );
+ 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() {
expect(45);
-
var div = jQuery("div"), old = div.map(function(){
- return jQuery(this).attr("class");
+ return jQuery(this).attr("class") || "";
});
-
+
div.addClass(function(i, val) {
- if ( this.id !== "_firebugConsole" ) {
+ if ( this.id !== "_firebugConsole") {
equals( val, old[i], "Make sure the incoming value is correct." );
return "test";
}
});
var pass = true;
- for ( var i = 0; i < div.size(); i++ ) {
- if ( div.get(i).className.indexOf("test") == -1 ) pass = false;
+ for ( var i = 0; i < div.length; i++ ) {
+ if ( div.get(i).className.indexOf("test") == -1 ) pass = false;
}
ok( pass, "Add Class" );
});
@@ -843,4 +888,4 @@ test("addClass, removeClass, hasClass", function() {
ok( jq.hasClass("cla.ss3")==false, "Check the dotted class has been removed" );
jq.removeClass("class4");
ok( jq.hasClass("class4")==false, "Check the class has been properly removed" );
-});
+}); \ No newline at end of file
diff --git a/test/unit/core.js b/test/unit/core.js
index 79710025e..c2a23b1a8 100644
--- a/test/unit/core.js
+++ b/test/unit/core.js
@@ -642,7 +642,7 @@ test("first()/last()", function() {
});
test("map()", function() {
- expect(2);//expect(6);
+ expect(7);
same(
jQuery("#ap").map(function(){
@@ -660,32 +660,32 @@ test("map()", function() {
"Single Map"
);
- return;//these haven't been accepted yet
-
//for #2616
var keys = jQuery.map( {a:1,b:2}, function( v, k ){
return k;
- }, [ ] );
-
+ });
equals( keys.join(""), "ab", "Map the keys from a hash to an array" );
var values = jQuery.map( {a:1,b:2}, function( v, k ){
return v;
- }, [ ] );
-
+ });
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 mapped = jQuery.map( scripts, function( v, k ){
return v;
- }, {length:0} );
-
+ });
equals( mapped.length, scripts.length, "Map an array(-like) to a hash" );
var flat = jQuery.map( Array(4), function( v, k ){
return k % 2 ? k : [k,k,k];//try mixing array and regular returns
});
-
equals( flat.join(""), "00012223", "try the new flatten technique(#2616)" );
});
@@ -903,7 +903,7 @@ test("jQuery.isEmptyObject", function(){
});
test("jQuery.proxy", function(){
- expect(4);
+ expect(6);
var test = function(){ equals( this, thisObject, "Make sure that scope is set properly." ); };
var thisObject = { foo: "bar", method: test };
@@ -917,8 +917,17 @@ test("jQuery.proxy", function(){
// Make sure it doesn't freak out
equals( jQuery.proxy( null, thisObject ), undefined, "Make sure no function was returned." );
- // Use the string shortcut
- jQuery.proxy( thisObject, "method" )();
+ // Partial application
+ 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(){
diff --git a/test/unit/data.js b/test/unit/data.js
index 8fb7f35ad..94fa2a018 100644
--- a/test/unit/data.js
+++ b/test/unit/data.js
@@ -485,4 +485,21 @@ if (window.JSON && window.JSON.stringify) {
equals( JSON.stringify(obj), '{"foo":"bar"}', "Expando is hidden from JSON.stringify" );
});
-} \ No newline at end of file
+}
+
+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();
+}); \ No newline at end of file
diff --git a/test/unit/event.js b/test/unit/event.js
index 50bf4e174..cefdf5833 100644
--- a/test/unit/event.js
+++ b/test/unit/event.js
@@ -975,6 +975,27 @@ test("trigger(eventObject, [data], [fn])", function() {
$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(){
expect(1);
@@ -2151,3 +2172,4 @@ test("event properties", function() {
}).click();
});
*/
+
diff --git a/test/unit/manipulation.js b/test/unit/manipulation.js
index ff3dff164..e972a4792 100644
--- a/test/unit/manipulation.js
+++ b/test/unit/manipulation.js
@@ -1009,7 +1009,7 @@ test("clone()", 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>");
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[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'>");
clone = element.clone();
diff --git a/test/unit/traversing.js b/test/unit/traversing.js
index f5108bdef..6228a0b98 100644
--- a/test/unit/traversing.js
+++ b/test/unit/traversing.js
@@ -13,8 +13,32 @@ test("find(String)", function() {
same( jQuery("#main").find("> #foo > p").get(), q("sndp", "en", "sap"), "find child elements" );
});
-test("is(String)", function() {
- expect(26);
+test("find(node|jQuery object)", function() {
+ 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('div'), 'Check for element: A form is not a div' );
ok( jQuery('#mark').is('.blog'), 'Check for class: Expected class "blog"' );
@@ -33,11 +57,13 @@ test("is(String)", function() {
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):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(null), 'Expected false for an invalid expression - null' );
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({ plain: "object" }), 'Check passing invalid object' );
+
// 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="de"],[lang="en"]'), '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' );
});
+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() {
expect(1);
@@ -82,11 +138,16 @@ test("index(Object|String|undefined)", function() {
equals( jQuery('#radio2').index('#form :text') , -1, "Check for index not found within a selector" );
});
-test("filter(Selector)", function() {
- expect(5);
+test("filter(Selector|undefined)", function() {
+ expect(9);
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(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
var j = jQuery("#nonnodes").contents();
@@ -124,7 +185,7 @@ test("filter(jQuery)", function() {
})
test("closest()", function() {
- expect(11);
+ expect(13);
same( jQuery("body").closest("body").get(), q("body"), "closest(body)" );
same( jQuery("body").closest("html").get(), q("html"), "closest(html)" );
same( jQuery("body").closest("div").get(), [], "closest(div)" );
@@ -144,6 +205,10 @@ test("closest()", function() {
// Test on disconnected node
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() {
@@ -158,8 +223,29 @@ test("closest(Array)", function() {
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() {
expect(7);
+>>>>>>> 1a167767305202797cf4c839eb64bd7adfb00182
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("#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, #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')");
+
+ 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() {