Commit d0388e9e authored by Gilad Peleg's avatar Gilad Peleg Committed by Oleg Gaidarenko

Core: organize prop & attr code to be similar

Ref 5153b5334eb2c8317372b46209bd9d092a91afdc
Closes gh-2426
parent 6df1bf9b
define([ define([
"../core", "../core",
"../var/rnotwhite",
"../core/access", "../core/access",
"./support", "./support",
"./val", "../var/rnotwhite",
"../selector" "../selector"
], function( jQuery, rnotwhite, access, support ) { ], function( jQuery, access, support, rnotwhite ) {
var boolHook, var boolHook,
attrHandle = jQuery.expr.attrHandle, attrHandle = jQuery.expr.attrHandle;
ruseDefault = /^(?:checked|selected)$/i,
getSetInput = support.input;
jQuery.fn.extend({ jQuery.fn.extend({
attr: function( name, value ) { attr: function( name, value ) {
...@@ -26,10 +23,10 @@ jQuery.fn.extend({ ...@@ -26,10 +23,10 @@ jQuery.fn.extend({
jQuery.extend({ jQuery.extend({
attr: function( elem, name, value ) { attr: function( elem, name, value ) {
var hooks, ret, var ret, hooks,
nType = elem.nodeType; nType = elem.nodeType;
// don't get/set attributes on text, comment and attribute nodes // Don't get/set attributes on text, comment and attribute nodes
if ( nType === 3 || nType === 8 || nType === 2 ) { if ( nType === 3 || nType === 8 || nType === 2 ) {
return; return;
} }
...@@ -48,30 +45,43 @@ jQuery.extend({ ...@@ -48,30 +45,43 @@ jQuery.extend({
} }
if ( value !== undefined ) { if ( value !== undefined ) {
if ( value === null ) { if ( value === null ) {
jQuery.removeAttr( elem, name ); jQuery.removeAttr( elem, name );
return;
}
} else if ( hooks && "set" in hooks && if ( hooks && "set" in hooks &&
(ret = hooks.set( elem, value, name )) !== undefined ) { ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
return ret; return ret;
} else {
elem.setAttribute( name, value + "" );
return value;
} }
} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) { elem.setAttribute( name, value + "" );
return value;
}
if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
return ret; return ret;
}
} else { ret = jQuery.find.attr( elem, name );
ret = jQuery.find.attr( elem, name );
// Non-existent attributes return null, we normalize to undefined // Non-existent attributes return null, we normalize to undefined
return ret == null ? return ret == null ? undefined : ret;
undefined : },
ret;
attrHooks: {
type: {
set: function( elem, value ) {
if ( !support.radioValue && value === "radio" &&
jQuery.nodeName( elem, "input" ) ) {
var val = elem.value;
elem.setAttribute( "type", value );
if ( val ) {
elem.value = val;
}
return value;
}
}
} }
}, },
...@@ -81,116 +91,50 @@ jQuery.extend({ ...@@ -81,116 +91,50 @@ jQuery.extend({
attrNames = value && value.match( rnotwhite ); attrNames = value && value.match( rnotwhite );
if ( attrNames && elem.nodeType === 1 ) { if ( attrNames && elem.nodeType === 1 ) {
while ( (name = attrNames[i++]) ) { while ( ( name = attrNames[i++] ) ) {
propName = jQuery.propFix[ name ] || name; propName = jQuery.propFix[ name ] || name;
// Boolean attributes get special treatment (#10870) // Boolean attributes get special treatment (#10870)
if ( jQuery.expr.match.bool.test( name ) ) { if ( jQuery.expr.match.bool.test( name ) ) {
// Set corresponding property to false // Set corresponding property to false
if ( getSetInput || !ruseDefault.test( name ) ) { elem[ propName ] = false;
elem[ propName ] = false;
// Support: IE<9
// Also clear defaultChecked/defaultSelected (if appropriate)
} else {
elem[ jQuery.camelCase( "default-" + name ) ] =
elem[ propName ] = false;
}
} }
elem.removeAttribute( name ); elem.removeAttribute( name );
} }
} }
},
attrHooks: {
type: {
set: function( elem, value ) {
if ( !support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) {
// Setting the type on a radio button after the value resets the value in IE8-9
// Reset value to default in case type is set after value during creation
var val = elem.value;
elem.setAttribute( "type", value );
if ( val ) {
elem.value = val;
}
return value;
}
}
}
} }
}); });
// Hook for boolean attributes // Hooks for boolean attributes
boolHook = { boolHook = {
set: function( elem, value, name ) { set: function( elem, value, name ) {
if ( value === false ) { if ( value === false ) {
// Remove boolean attributes when set to false // Remove boolean attributes when set to false
jQuery.removeAttr( elem, name ); jQuery.removeAttr( elem, name );
} else if ( getSetInput || !ruseDefault.test( name ) ) {
elem.setAttribute( jQuery.propFix[ name ] || name, name );
} else { } else {
// Support: IE<9 elem.setAttribute( name, name );
// Use defaultChecked and defaultSelected for oldIE
elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
} }
return name; return name;
} }
}; };
// Retrieve booleans specially
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) { jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
var getter = attrHandle[ name ] || jQuery.find.attr; var getter = attrHandle[ name ] || jQuery.find.attr;
attrHandle[ name ] = getSetInput || !ruseDefault.test( name ) ? attrHandle[ name ] = function( elem, name, isXML ) {
function( elem, name, isXML ) { var ret, handle;
var ret, handle; if ( !isXML ) {
if ( !isXML ) { // Avoid an infinite loop by temporarily removing this function from the getter
// Avoid an infinite loop by temporarily removing this function from the getter handle = attrHandle[ name ];
handle = attrHandle[ name ]; attrHandle[ name ] = ret;
attrHandle[ name ] = ret; ret = getter( elem, name, isXML ) != null ?
ret = getter( elem, name, isXML ) != null ? name.toLowerCase() :
name.toLowerCase() : null;
null; attrHandle[ name ] = handle;
attrHandle[ name ] = handle;
}
return ret;
} :
function( elem, name, isXML ) {
if ( !isXML ) {
return elem[ jQuery.camelCase( "default-" + name ) ] ?
name.toLowerCase() :
null;
}
};
});
// fix oldIE attroperties
if ( !getSetInput ) {
jQuery.attrHooks.value = {
set: function( elem, value ) {
if ( jQuery.nodeName( elem, "input" ) ) {
// Does not return so that setAttribute is also used
elem.defaultValue = value;
}
} }
return ret;
}; };
} });
if ( !support.style ) {
jQuery.attrHooks.style = {
get: function( elem ) {
// Return undefined in the case of empty string
// Note: IE uppercases css property names, but if we were to .toLowerCase()
// .cssText, that would destroy case senstitivity in URL's, like in "background"
return elem.style.cssText || undefined;
},
set: function( elem, value ) {
return ( elem.style.cssText = value + "" );
}
};
}
}); });
define([ define([
"../core", "../core",
"../core/access", "../core/access",
"./support" "./support",
"../selector"
], function( jQuery, access, support ) { ], function( jQuery, access, support ) {
var rfocusable = /^(?:input|select|textarea|button|object)$/i, var rfocusable = /^(?:input|select|textarea|button)$/i;
rclickable = /^(?:a|area)$/i;
jQuery.fn.extend({ jQuery.fn.extend({
prop: function( name, value ) { prop: function( name, value ) {
...@@ -13,70 +13,59 @@ jQuery.fn.extend({ ...@@ -13,70 +13,59 @@ jQuery.fn.extend({
}, },
removeProp: function( name ) { removeProp: function( name ) {
name = jQuery.propFix[ name ] || name;
return this.each(function() { return this.each(function() {
// try/catch handles cases where IE balks (such as removing a property on window) delete this[ jQuery.propFix[ name ] || name ];
try {
this[ name ] = undefined;
delete this[ name ];
} catch ( e ) {}
}); });
} }
}); });
jQuery.extend({ jQuery.extend({
propFix: {
"for": "htmlFor",
"class": "className"
},
prop: function( elem, name, value ) { prop: function( elem, name, value ) {
var ret, hooks, notxml, var ret, hooks,
nType = elem.nodeType; nType = elem.nodeType;
// don't get/set properties on text, comment and attribute nodes // Don't get/set properties on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { if ( nType === 3 || nType === 8 || nType === 2 ) {
return; return;
} }
notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
if ( notxml ) {
// Fix name and attach hooks // Fix name and attach hooks
name = jQuery.propFix[ name ] || name; name = jQuery.propFix[ name ] || name;
hooks = jQuery.propHooks[ name ]; hooks = jQuery.propHooks[ name ];
} }
if ( value !== undefined ) { if ( value !== undefined ) {
return hooks && "set" in hooks && if ( hooks && "set" in hooks &&
(ret = hooks.set( elem, value, name )) !== undefined ? ( ret = hooks.set( elem, value, name ) ) !== undefined ) {
ret : return ret;
( elem[ name ] = value ); }
} else { return ( elem[ name ] = value );
return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ? }
ret :
elem[ name ]; if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
return ret;
} }
return elem[ name ];
}, },
propHooks: { propHooks: {
tabIndex: { tabIndex: {
get: function( elem ) { get: function( elem ) {
// elem.tabIndex doesn't always return the return elem.hasAttribute( "tabindex" ) ||
// correct value when it hasn't been explicitly set rfocusable.test( elem.nodeName ) || elem.href ?
// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ elem.tabIndex :
// Use proper attribute retrieval(#12072) -1;
var tabindex = jQuery.find.attr( elem, "tabindex" );
return tabindex ?
parseInt( tabindex, 10 ) :
rfocusable.test( elem.nodeName ) ||
rclickable.test( elem.nodeName ) && elem.href ?
0 :
-1;
} }
} }
},
propFix: {
"for": "htmlFor",
"class": "className"
} }
}); });
...@@ -84,14 +73,8 @@ if ( !support.optSelected ) { ...@@ -84,14 +73,8 @@ if ( !support.optSelected ) {
jQuery.propHooks.selected = { jQuery.propHooks.selected = {
get: function( elem ) { get: function( elem ) {
var parent = elem.parentNode; var parent = elem.parentNode;
if ( parent && parent.parentNode ) {
if ( parent ) { parent.parentNode.selectedIndex;
parent.selectedIndex;
// Make sure that it also works with optgroups, see #5701
if ( parent.parentNode ) {
parent.parentNode.selectedIndex;
}
} }
return null; return null;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment