mirror of
https://github.com/jquery/jquery.git
synced 2026-04-20 03:01:22 -04:00
Fix #13539: Utilize Sizzle hooks. Close gh-1215.
This commit is contained in:
@@ -3,7 +3,6 @@ var nodeHook, boolHook,
|
||||
rreturn = /\r/g,
|
||||
rfocusable = /^(?:input|select|textarea|button|object)$/i,
|
||||
rclickable = /^(?:a|area)$/i,
|
||||
rboolean = /^(?:checked|selected|autofocus|autoplay|async|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped)$/i,
|
||||
ruseDefault = /^(?:checked|selected)$/i,
|
||||
getSetAttribute = jQuery.support.getSetAttribute,
|
||||
getSetInput = jQuery.support.input;
|
||||
@@ -297,7 +296,7 @@ jQuery.extend({
|
||||
},
|
||||
|
||||
attr: function( elem, name, value ) {
|
||||
var hooks, notxml, ret,
|
||||
var hooks, ret,
|
||||
nType = elem.nodeType;
|
||||
|
||||
// don't get/set attributes on text, comment and attribute nodes
|
||||
@@ -310,13 +309,12 @@ jQuery.extend({
|
||||
return jQuery.prop( elem, name, value );
|
||||
}
|
||||
|
||||
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
|
||||
|
||||
// All attributes are lowercase
|
||||
// Grab necessary hook if one is defined
|
||||
if ( notxml ) {
|
||||
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
|
||||
name = name.toLowerCase();
|
||||
hooks = jQuery.attrHooks[ name ] || ( rboolean.test( name ) ? boolHook : nodeHook );
|
||||
hooks = jQuery.attrHooks[ name ] ||
|
||||
( jQuery.expr.match.boolean.test( name ) ? boolHook : nodeHook );
|
||||
}
|
||||
|
||||
if ( value !== undefined ) {
|
||||
@@ -324,7 +322,7 @@ jQuery.extend({
|
||||
if ( value === null ) {
|
||||
jQuery.removeAttr( elem, name );
|
||||
|
||||
} else if ( hooks && notxml && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
|
||||
} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
|
||||
return ret;
|
||||
|
||||
} else {
|
||||
@@ -332,16 +330,11 @@ jQuery.extend({
|
||||
return value;
|
||||
}
|
||||
|
||||
} else if ( hooks && notxml && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
|
||||
} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
|
||||
return ret;
|
||||
|
||||
} else {
|
||||
|
||||
// In IE9+, Flash objects don't have .getAttribute (#12945)
|
||||
// Support: IE9+
|
||||
if ( typeof elem.getAttribute !== core_strundefined ) {
|
||||
ret = elem.getAttribute( name );
|
||||
}
|
||||
ret = jQuery.find.attr( elem, name );
|
||||
|
||||
// Non-existent attributes return null, we normalize to undefined
|
||||
return ret == null ?
|
||||
@@ -360,14 +353,15 @@ jQuery.extend({
|
||||
propName = jQuery.propFix[ name ] || name;
|
||||
|
||||
// Boolean attributes get special treatment (#10870)
|
||||
if ( rboolean.test( name ) ) {
|
||||
if ( jQuery.expr.match.boolean.test( name ) ) {
|
||||
// Set corresponding property to false for boolean attributes
|
||||
// Also clear defaultChecked/defaultSelected (if appropriate) for IE<8
|
||||
if ( !getSetAttribute && ruseDefault.test( name ) ) {
|
||||
if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
|
||||
elem[ propName ] = false;
|
||||
// Support: IE<9
|
||||
// Also clear defaultChecked/defaultSelected (if appropriate)
|
||||
} else {
|
||||
elem[ jQuery.camelCase( "default-" + name ) ] =
|
||||
elem[ propName ] = false;
|
||||
} else {
|
||||
elem[ propName ] = false;
|
||||
}
|
||||
|
||||
// See #9699 for explanation of this approach (setting first, then removal)
|
||||
@@ -398,18 +392,8 @@ jQuery.extend({
|
||||
},
|
||||
|
||||
propFix: {
|
||||
tabindex: "tabIndex",
|
||||
readonly: "readOnly",
|
||||
"for": "htmlFor",
|
||||
"class": "className",
|
||||
maxlength: "maxLength",
|
||||
cellspacing: "cellSpacing",
|
||||
cellpadding: "cellPadding",
|
||||
rowspan: "rowSpan",
|
||||
colspan: "colSpan",
|
||||
usemap: "useMap",
|
||||
frameborder: "frameBorder",
|
||||
contenteditable: "contentEditable"
|
||||
"class": "className"
|
||||
},
|
||||
|
||||
prop: function( elem, name, value ) {
|
||||
@@ -464,32 +448,8 @@ jQuery.extend({
|
||||
}
|
||||
});
|
||||
|
||||
// Hook for boolean attributes
|
||||
// Hooks for boolean attributes
|
||||
boolHook = {
|
||||
get: function( elem, name ) {
|
||||
var
|
||||
// Use .prop to determine if this attribute is understood as boolean
|
||||
prop = jQuery.prop( elem, name ),
|
||||
|
||||
// Fetch it accordingly
|
||||
attr = typeof prop === "boolean" && elem.getAttribute( name ),
|
||||
detail = typeof prop === "boolean" ?
|
||||
|
||||
getSetInput && getSetAttribute ?
|
||||
attr != null :
|
||||
// oldIE fabricates an empty string for missing boolean attributes
|
||||
// and conflates checked/selected into attroperties
|
||||
ruseDefault.test( name ) ?
|
||||
elem[ jQuery.camelCase( "default-" + name ) ] :
|
||||
!!attr :
|
||||
|
||||
// fetch an attribute node for properties not recognized as boolean
|
||||
elem.getAttributeNode( name );
|
||||
|
||||
return detail && detail.value !== false ?
|
||||
name.toLowerCase() :
|
||||
undefined;
|
||||
},
|
||||
set: function( elem, value, name ) {
|
||||
if ( value === false ) {
|
||||
// Remove boolean attributes when set to false
|
||||
@@ -506,19 +466,44 @@ boolHook = {
|
||||
return name;
|
||||
}
|
||||
};
|
||||
jQuery.each( jQuery.expr.match.boolean.source.match( /\w+/g ), function( i, name ) {
|
||||
var getter = jQuery.expr.attrHandle[ name ] || jQuery.find.attr;
|
||||
|
||||
// fix oldIE value attroperty
|
||||
jQuery.expr.attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
|
||||
function( elem, name, isXML ) {
|
||||
var fn = jQuery.expr.attrHandle[ name ],
|
||||
ret = isXML ?
|
||||
undefined :
|
||||
/* jshint eqeqeq: false */
|
||||
(jQuery.expr.attrHandle[ name ] = undefined) !=
|
||||
getter( elem, name, isXML ) ?
|
||||
|
||||
name.toLowerCase() :
|
||||
null;
|
||||
jQuery.expr.attrHandle[ name ] = fn;
|
||||
return ret;
|
||||
} :
|
||||
function( elem, name, isXML ) {
|
||||
return isXML ?
|
||||
undefined :
|
||||
elem[ jQuery.camelCase( "default-" + name ) ] ?
|
||||
name.toLowerCase() :
|
||||
null;
|
||||
};
|
||||
});
|
||||
|
||||
// fix oldIE attroperties
|
||||
if ( !getSetInput || !getSetAttribute ) {
|
||||
jQuery.expr.attrHandle.value = function( elem, name, isXML ) {
|
||||
var ret = elem.getAttributeNode( name );
|
||||
return isXML ? undefined : jQuery.nodeName( elem, "input" ) ?
|
||||
|
||||
// Ignore the value *property* by using defaultValue
|
||||
elem.defaultValue :
|
||||
|
||||
ret && ret.specified ? ret.value : undefined;
|
||||
};
|
||||
jQuery.attrHooks.value = {
|
||||
get: function( elem, name ) {
|
||||
var ret = elem.getAttributeNode( name );
|
||||
return jQuery.nodeName( elem, "input" ) ?
|
||||
|
||||
// Ignore the value *property* by using defaultValue
|
||||
elem.defaultValue :
|
||||
|
||||
ret && ret.specified ? ret.value : undefined;
|
||||
},
|
||||
set: function( elem, value, name ) {
|
||||
if ( jQuery.nodeName( elem, "input" ) ) {
|
||||
// Does not return so that setAttribute is also used
|
||||
@@ -536,13 +521,7 @@ if ( !getSetAttribute ) {
|
||||
|
||||
// Use this for any attribute in IE6/7
|
||||
// This fixes almost every IE6/7 issue
|
||||
nodeHook = jQuery.valHooks.button = {
|
||||
get: function( elem, name ) {
|
||||
var ret = elem.getAttributeNode( name );
|
||||
return ret && ( name === "id" || name === "name" || name === "coords" ? ret.value !== "" : ret.specified ) ?
|
||||
ret.value :
|
||||
undefined;
|
||||
},
|
||||
nodeHook = {
|
||||
set: function( elem, value, name ) {
|
||||
// Set the existing or create a new attribute node
|
||||
var ret = elem.getAttributeNode( name );
|
||||
@@ -560,11 +539,29 @@ if ( !getSetAttribute ) {
|
||||
undefined;
|
||||
}
|
||||
};
|
||||
jQuery.expr.attrHandle.id = jQuery.expr.attrHandle.name = jQuery.expr.attrHandle.coords =
|
||||
// Some attributes are constructed with empty-string values when not defined
|
||||
function( elem, name, isXML ) {
|
||||
var ret;
|
||||
return isXML ?
|
||||
undefined :
|
||||
(ret = elem.getAttributeNode( name )) && ret.value !== "" ?
|
||||
ret.value :
|
||||
null;
|
||||
};
|
||||
jQuery.valHooks.button = {
|
||||
get: function( elem, name ) {
|
||||
var ret = elem.getAttributeNode( name );
|
||||
return ret && ret.specified ?
|
||||
ret.value :
|
||||
undefined;
|
||||
},
|
||||
set: nodeHook.set
|
||||
};
|
||||
|
||||
// Set contenteditable to false on removals(#10429)
|
||||
// Setting to empty string throws an error as an invalid value
|
||||
jQuery.attrHooks.contenteditable = {
|
||||
get: nodeHook.get,
|
||||
set: function( elem, value, name ) {
|
||||
nodeHook.set( elem, value === "" ? false : value, name );
|
||||
}
|
||||
@@ -573,14 +570,14 @@ if ( !getSetAttribute ) {
|
||||
// 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 ], {
|
||||
jQuery.attrHooks[ name ] = {
|
||||
set: function( elem, value ) {
|
||||
if ( value === "" ) {
|
||||
elem.setAttribute( name, "auto" );
|
||||
return value;
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -588,15 +585,6 @@ if ( !getSetAttribute ) {
|
||||
// Some attributes require a special call on IE
|
||||
// http://msdn.microsoft.com/en-us/library/ms536429%28VS.85%29.aspx
|
||||
if ( !jQuery.support.hrefNormalized ) {
|
||||
jQuery.each([ "href", "src", "width", "height" ], 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;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// href/src property should get the full normalized URL (#10299/#12915)
|
||||
jQuery.each([ "href", "src" ], function( i, name ) {
|
||||
jQuery.propHooks[ name ] = {
|
||||
@@ -624,7 +612,7 @@ if ( !jQuery.support.style ) {
|
||||
// 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, {
|
||||
jQuery.propHooks.selected = {
|
||||
get: function( elem ) {
|
||||
var parent = elem.parentNode;
|
||||
|
||||
@@ -638,31 +626,43 @@ if ( !jQuery.support.optSelected ) {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
jQuery.each([
|
||||
"tabIndex",
|
||||
"readOnly",
|
||||
"maxLength",
|
||||
"cellSpacing",
|
||||
"cellPadding",
|
||||
"rowSpan",
|
||||
"colSpan",
|
||||
"useMap",
|
||||
"frameBorder",
|
||||
"contentEditable"
|
||||
], function() {
|
||||
jQuery.propFix[ this.toLowerCase() ] = this;
|
||||
});
|
||||
|
||||
// IE6/7 call enctype encoding
|
||||
if ( !jQuery.support.enctype ) {
|
||||
jQuery.propFix.enctype = "encoding";
|
||||
}
|
||||
|
||||
// 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 ], {
|
||||
jQuery.valHooks[ this ] = {
|
||||
set: function( elem, value ) {
|
||||
if ( jQuery.isArray( value ) ) {
|
||||
return ( elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0 );
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
if ( !jQuery.support.checkOn ) {
|
||||
jQuery.valHooks[ this ].get = function( elem ) {
|
||||
// Support: Webkit
|
||||
// "" is returned instead of "on" if a value isn't specified
|
||||
return elem.getAttribute("value") === null ? "on" : elem.value;
|
||||
};
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user