diff options
author | Richard Gibson <richard.gibson@gmail.com> | 2012-11-26 03:20:43 -0500 |
---|---|---|
committer | jaubourg <j@ubourg.net> | 2012-11-27 01:59:22 +0100 |
commit | 0877d424e08d57e6f0d1da9a86289fb10d0ee136 (patch) | |
tree | c73d6ee4d3d77264336c19e6cf2d8f94c4afad8f /src/attributes.js | |
parent | 512b826f9f14e30b715b943547b97aaaf1099f4e (diff) | |
download | jquery-0877d424e08d57e6f0d1da9a86289fb10d0ee136.tar.gz jquery-0877d424e08d57e6f0d1da9a86289fb10d0ee136.zip |
Fix #12959: Optimize library-wide patterns
Diffstat (limited to 'src/attributes.js')
-rw-r--r-- | src/attributes.js | 115 |
1 files changed, 57 insertions, 58 deletions
diff --git a/src/attributes.js b/src/attributes.js index 919733cd8..ac4b3c866 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -1,9 +1,9 @@ var nodeHook, boolHook, fixSpecified, rclass = /[\t\r\n]/g, rreturn = /\r/g, - rtype = /^(?:button|input)$/i, - rfocusable = /^(?:button|input|object|select|textarea)$/i, - rclickable = /^a(?:rea|)$/i, + rtype = /^(?:input|button)$/i, + rfocusable = /^(?:input|select|textarea|button|object)$/i, + rclickable = /^(?:a|area)$/i, rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, getSetAttribute = jQuery.support.getSetAttribute; @@ -34,35 +34,36 @@ jQuery.fn.extend({ }, addClass: function( value ) { - var classNames, i, l, elem, - setClass, c, cl; + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = typeof value === "string" && value; if ( jQuery.isFunction( value ) ) { return this.each(function( j ) { - jQuery( this ).addClass( value.call(this, j, this.className) ); + jQuery( this ).addClass( value.call( this, j, this.className ) ); }); } - if ( value && typeof value === "string" ) { - classNames = value.split( core_rspace ); + if ( proceed ) { + // The disjunction here is for better compressibility (see removeClass) + classes = ( value || "" ).match( core_rnotwhite ) || []; - for ( i = 0, l = this.length; i < l; i++ ) { + for ( ; i < len; i++ ) { elem = this[ i ]; if ( elem.nodeType === 1 ) { - if ( !elem.className && classNames.length === 1 ) { - elem.className = value; - - } else { - setClass = " " + elem.className + " "; - - for ( c = 0, cl = classNames.length; c < cl; c++ ) { - if ( setClass.indexOf( " " + classNames[ c ] + " " ) < 0 ) { - setClass += classNames[ c ] + " "; - } + cur = elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " "; + j = 0; + while ( (clazz = classes[j++]) ) { + if ( cur.indexOf( " " + clazz + " " ) < 0 ) { + cur += clazz + " "; } - elem.className = jQuery.trim( setClass ); } + elem.className = jQuery.trim( cur ); + } } } @@ -71,30 +72,34 @@ jQuery.fn.extend({ }, removeClass: function( value ) { - var removes, className, elem, c, cl, i, l; + var classes, elem, cur, clazz, j, + i = 0, + len = this.length, + proceed = arguments.length === 0 || typeof value === "string" && value; if ( jQuery.isFunction( value ) ) { return this.each(function( j ) { - jQuery( this ).removeClass( value.call(this, j, this.className) ); + jQuery( this ).removeClass( value.call( this, j, this.className ) ); }); } - if ( (value && typeof value === "string") || !arguments.length ) { - removes = ( value || "" ).split( core_rspace ); + if ( proceed ) { + classes = ( value || "" ).match( core_rnotwhite ) || []; - for ( i = 0, l = this.length; i < l; i++ ) { + for ( ; i < len; i++ ) { elem = this[ i ]; - if ( elem.nodeType === 1 && elem.className ) { - - className = (" " + elem.className + " ").replace( rclass, " " ); - - // loop over each item in the removal list - for ( c = 0, cl = removes.length; c < cl; c++ ) { - // Remove until there is nothing to remove, - while ( className.indexOf(" " + removes[ c ] + " ") >= 0 ) { - className = className.replace( " " + removes[ c ] + " " , " " ); + if ( elem.nodeType === 1 ) { + // This expression is here for better compressibility (see addClass) + cur = elem.className ? + ( " " + elem.className + " " ).replace( rclass, " " ) : + " "; + j = 0; + while ( (clazz = classes[j++]) ) { + // Remove *all* instances + while ( cur.indexOf( " " + clazz + " " ) >= 0 ) { + cur = cur.replace( " " + clazz + " ", " " ); } } - elem.className = value ? jQuery.trim( className ) : ""; + elem.className = value ? jQuery.trim( cur ) : ""; } } } @@ -119,7 +124,7 @@ jQuery.fn.extend({ i = 0, self = jQuery( this ), state = stateVal, - classNames = value.split( core_rspace ); + classNames = value.match( core_rnotwhite ) || []; while ( (className = classNames[ i++ ]) ) { // check each className given, space separated list @@ -331,31 +336,25 @@ jQuery.extend({ }, removeAttr: function( elem, value ) { - var propName, attrNames, name, isBool, - i = 0; - - if ( value && elem.nodeType === 1 ) { - - attrNames = value.split( core_rspace ); - - for ( ; i < attrNames.length; i++ ) { - name = attrNames[ i ]; + var name, propName, isBool, + i = 0, + attrNames = value && value.match( core_rnotwhite ); - if ( name ) { - propName = jQuery.propFix[ name ] || name; - isBool = rboolean.test( name ); + if ( attrNames && elem.nodeType === 1 ) { + while ( (name = attrNames[i++]) ) { + propName = jQuery.propFix[ name ] || name; + isBool = rboolean.test( name ); - // See #9699 for explanation of this approach (setting first, then removal) - // Do not do this for boolean attributes (see #10870) - if ( !isBool ) { - jQuery.attr( elem, name, "" ); - } - elem.removeAttribute( getSetAttribute ? name : propName ); + // See #9699 for explanation of this approach (setting first, then removal) + // Do not do this for boolean attributes (see #10870) + if ( !isBool ) { + jQuery.attr( elem, name, "" ); + } + elem.removeAttribute( getSetAttribute ? name : propName ); - // Set corresponding property to false for boolean attributes - if ( isBool && propName in elem ) { - elem[ propName ] = false; - } + // Set corresponding property to false for boolean attributes + if ( isBool && propName in elem ) { + elem[ propName ] = false; } } } |