diff --git a/src/attributes.js b/src/attributes.js index 345845689..6dc39b97c 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -7,6 +7,7 @@ var rclass = /[\n\t\r]/g, rfocusable = /^(?:button|input|object|select|textarea)$/i, rclickable = /^a(?:rea)?$/i, rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + getSetAttribute = jQuery.support.getSetAttribute, nodeHook, boolHook, fixSpecified; jQuery.fn.extend({ @@ -143,8 +144,10 @@ jQuery.fn.extend({ }, hasClass: function( selector ) { - var className = " " + selector + " "; - for ( var i = 0, l = this.length; i < l; i++ ) { + var className = " " + selector + " ", + i = 0, + l = this.length; + for ( ; i < l; i++ ) { if ( this[i].nodeType === 1 && (" " + this[i].className + " ").replace(rclass, " ").indexOf( className ) > -1 ) { return true; } @@ -154,7 +157,7 @@ jQuery.fn.extend({ }, val: function( value ) { - var hooks, ret, + var hooks, ret, isFunction, elem = this[0]; if ( !arguments.length ) { @@ -177,7 +180,7 @@ jQuery.fn.extend({ return undefined; } - var isFunction = jQuery.isFunction( value ); + isFunction = jQuery.isFunction( value ); return this.each(function( i ) { var self = jQuery(this), val; @@ -225,7 +228,7 @@ jQuery.extend({ }, select: { get: function( elem ) { - var value, + var value, i, max, option, index = elem.selectedIndex, values = [], options = elem.options, @@ -237,8 +240,10 @@ jQuery.extend({ } // 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 ]; + i = one ? index : 0; + max = one ? index + 1 : options.length; + for ( ; i < max; i++ ) { + 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) && @@ -292,7 +297,8 @@ jQuery.extend({ }, attr: function( elem, name, value, pass ) { - var nType = elem.nodeType; + var ret, hooks, notxml, + nType = elem.nodeType; // don't get/set attributes on text, comment and attribute nodes if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { @@ -308,8 +314,7 @@ jQuery.extend({ return jQuery.prop( elem, name, value ); } - var ret, hooks, - notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); // Normalize the name if needed if ( notxml ) { @@ -355,13 +360,14 @@ jQuery.extend({ for ( ; i < l; i++ ) { name = attrNames[ i ].toLowerCase(); + propName = jQuery.propFix[ name ] || name; // See #9699 for explanation of this approach (setting first, then removal) jQuery.attr( elem, name, "" ); - elem.removeAttribute( name ); + elem.removeAttribute( getSetAttribute ? name : propName ); // Set corresponding property to false for boolean attributes - if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) { + if ( rboolean.test( name ) && propName in elem ) { elem[ propName ] = false; } } @@ -424,15 +430,15 @@ jQuery.extend({ }, prop: function( elem, name, value ) { - var nType = elem.nodeType; + var ret, hooks, notxml, + 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 ); + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); if ( notxml ) { // Fix name and attach hooks @@ -510,7 +516,7 @@ boolHook = { }; // IE6/7 do not support getting/setting some attributes with get/setAttribute -if ( !jQuery.support.getSetAttribute ) { +if ( !getSetAttribute ) { fixSpecified = { name: true, diff --git a/test/unit/attributes.js b/test/unit/attributes.js index fd97d1c05..926ee6ff4 100644 --- a/test/unit/attributes.js +++ b/test/unit/attributes.js @@ -452,7 +452,9 @@ test("attr('tabindex', value)", function() { test("removeAttr(String)", function() { expect(9); - equal( jQuery("#mark").removeAttr( "class" )[0].className, "", "remove class" ); + var $first; + + equal( jQuery("#mark").removeAttr( "class" ).attr("class"), undefined, "remove class" ); equal( jQuery("#form").removeAttr("id").attr("id"), undefined, "Remove id" ); equal( jQuery("#foo").attr("style", "position:absolute;").removeAttr("style").attr("style"), undefined, "Check removing style attribute" ); equal( jQuery("#form").attr("style", "position:absolute;").removeAttr("style").attr("style"), undefined, "Check removing style attribute on a form" ); @@ -465,8 +467,8 @@ test("removeAttr(String)", function() { equal( document.getElementById("text1").readOnly, false, "removeAttr sets boolean properties to false" ); try { - jQuery("#first").attr("contenteditable", "true").removeAttr("contenteditable"); - ok( true, "Removing contenteditable does not throw an error."); + $first = jQuery("#first").attr("contenteditable", "true").removeAttr("contenteditable"); + equal( $first.attr('contenteditable'), undefined, "Remove the contenteditable attribute" ); } catch(e) { ok( false, "Removing contenteditable threw an error (#10429)" ); }