diff options
author | timmywil <tim.willison@thisismedium.com> | 2011-05-05 12:17:08 -0400 |
---|---|---|
committer | timmywil <tim.willison@thisismedium.com> | 2011-05-05 12:17:08 -0400 |
commit | 5097e6d1c672ef5fd3fcc0022ce84519233189cc (patch) | |
tree | 6f7c00f322174296be9158e3b26209e659010b69 /src | |
parent | 5195335cf4df62c06488807ae857f64c2d549253 (diff) | |
download | jquery-5097e6d1c672ef5fd3fcc0022ce84519233189cc.tar.gz jquery-5097e6d1c672ef5fd3fcc0022ce84519233189cc.zip |
Construct boolHook and rboolean regex to deal with boolean attributes. Fixes #9129. Fixes #9123.
- Construct regex for all attributes which are boolean attributes by specification.
+ This allows us to do what users expect with enumerated attributes and allows us to no longer complicate the issue.
+ People are just too confused with passing "true" instead of true when they should, so we won't have to worry about that anymore.
- Modularize code for dealing with boolean attributes into a separate hook to keep attr short and fast.
Diffstat (limited to 'src')
-rw-r--r-- | src/attributes.js | 86 |
1 files changed, 47 insertions, 39 deletions
diff --git a/src/attributes.js b/src/attributes.js index 991c2a204..c86916310 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -6,9 +6,9 @@ var rclass = /[\n\t\r]/g, rtype = /^(?:button|input)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i, rclickable = /^a(?:rea)?$/i, - rspecial = /^(?:data-|aria-)/, + rboolean = /^(?:autobuffer|autofocus|autoplay|async|checked|compact|controls|declare|defer|disabled|formnovalidate|ismap|loop|multiple|noresize|noshade|nowrap|novalidate|open|pubdate|readonly|required|reversed|seamless|selected)$/i, rinvalidChar = /\:/, - formHook; + formHook, boolHook; jQuery.fn.extend({ attr: function( name, value ) { @@ -301,22 +301,30 @@ jQuery.extend({ return jQuery( elem )[ name ]( value ); } - var ret, hooks, boolProp, + var ret, hooks, notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); // Normalize the name if needed name = notxml && jQuery.attrFix[ name ] || name; - // Get the appropriate hook, or the formHook - // if getSetAttribute is not supported and we have form objects in IE6/7 - hooks = jQuery.attrHooks[ name ] || - ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ? - formHook : - undefined ); + hooks = jQuery.attrHooks[ name ]; + + if ( !hooks ) { + // Use formHook for forms and if the name contains certain characters + if ( formHook && (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) { + hooks = formHook; + + // Use boolHook for boolean attributes + } else if ( rboolean.test( name ) && + (typeof value === "boolean" || value === undefined) ) { + + hooks = boolHook; + } + } if ( value !== undefined ) { - if ( value === null || (value === false && !rspecial.test( name )) ) { + if ( value === null ) { jQuery.removeAttr( elem, name ); return undefined; @@ -324,17 +332,6 @@ jQuery.extend({ return ret; } else { - - // Set boolean attributes to the same name - // Also set the DOM property - if ( value === true && !rspecial.test( name ) ) { - boolProp = jQuery.propFix[ name ] || name; - if ( !rinvalidChar.test( boolProp ) && typeof elem[ boolProp ] === "boolean" ) { - elem[ boolProp ] = true; - } - value = name.toLowerCase(); - } - elem.setAttribute( name, "" + value ); return value; } @@ -344,22 +341,12 @@ jQuery.extend({ } else { - // Align boolean attributes with corresponding properties - // Do not check the property if the name contains characters - // valid for attributes, but not for properties - if ( !rinvalidChar.test( name ) && typeof (boolProp = elem[ jQuery.propFix[ name ] || name ]) === "boolean" ) { - return boolProp ? - name.toLowerCase() : - undefined; - - } else { - ret = elem.getAttribute( name ); + ret = elem.getAttribute( name ); - // Non-existent attributes return null, we normalize to undefined - return ret === null ? - undefined : - ret; - } + // Non-existent attributes return null, we normalize to undefined + return ret === null ? + undefined : + ret; } }, @@ -376,9 +363,8 @@ jQuery.extend({ } // Set corresponding property to false for boolean attributes - name = jQuery.propFix[ name ] || name; - if ( !rinvalidChar.test( name ) && typeof elem[ name ] === "boolean" ) { - elem[ name ] = false; + if ( rboolean.test( name ) ) { + elem[ jQuery.propFix[ name ] || name ] = false; } } }, @@ -468,6 +454,28 @@ jQuery.extend({ propHooks: {} }); +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + return elem[ jQuery.propFix[ name ] || name ] ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + elem[ jQuery.propFix[ name ] || name ] = value; + elem.setAttribute( name, name.toLowerCase() ); + } + return name; + } +}; + // IE6/7 do not support getting/setting some attributes with get/setAttribute if ( !jQuery.support.getSetAttribute ) { |