define([
|
"../core",
|
"../var/rnotwhite",
|
"../var/strundefined",
|
"../core/access",
|
"./support",
|
"./val",
|
"../selector"
|
], function( jQuery, rnotwhite, strundefined, access, support ) {
|
|
var nodeHook, boolHook,
|
attrHandle = jQuery.expr.attrHandle,
|
ruseDefault = /^(?:checked|selected)$/i,
|
getSetAttribute = support.getSetAttribute,
|
getSetInput = support.input;
|
|
jQuery.fn.extend({
|
attr: function( name, value ) {
|
return access( this, jQuery.attr, name, value, arguments.length > 1 );
|
},
|
|
removeAttr: function( name ) {
|
return this.each(function() {
|
jQuery.removeAttr( this, name );
|
});
|
}
|
});
|
|
jQuery.extend({
|
attr: function( elem, name, value ) {
|
var hooks, ret,
|
nType = elem.nodeType;
|
|
// don't get/set attributes on text, comment and attribute nodes
|
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
|
return;
|
}
|
|
// Fallback to prop when attributes are not supported
|
if ( typeof elem.getAttribute === strundefined ) {
|
return jQuery.prop( elem, name, value );
|
}
|
|
// All attributes are lowercase
|
// Grab necessary hook if one is defined
|
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {
|
name = name.toLowerCase();
|
hooks = jQuery.attrHooks[ name ] ||
|
( jQuery.expr.match.bool.test( name ) ? boolHook : nodeHook );
|
}
|
|
if ( value !== undefined ) {
|
|
if ( value === null ) {
|
jQuery.removeAttr( elem, name );
|
|
} else if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) {
|
return ret;
|
|
} else {
|
elem.setAttribute( name, value + "" );
|
return value;
|
}
|
|
} else if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ) {
|
return ret;
|
|
} else {
|
ret = jQuery.find.attr( elem, name );
|
|
// Non-existent attributes return null, we normalize to undefined
|
return ret == null ?
|
undefined :
|
ret;
|
}
|
},
|
|
removeAttr: function( elem, value ) {
|
var name, propName,
|
i = 0,
|
attrNames = value && value.match( rnotwhite );
|
|
if ( attrNames && elem.nodeType === 1 ) {
|
while ( (name = attrNames[i++]) ) {
|
propName = jQuery.propFix[ name ] || name;
|
|
// Boolean attributes get special treatment (#10870)
|
if ( jQuery.expr.match.bool.test( name ) ) {
|
// Set corresponding property to false
|
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;
|
}
|
|
// See #9699 for explanation of this approach (setting first, then removal)
|
} else {
|
jQuery.attr( elem, name, "" );
|
}
|
|
elem.removeAttribute( getSetAttribute ? name : propName );
|
}
|
}
|
},
|
|
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 IE6-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
|
boolHook = {
|
set: function( elem, value, name ) {
|
if ( value === false ) {
|
// Remove boolean attributes when set to false
|
jQuery.removeAttr( elem, name );
|
} else if ( getSetInput && getSetAttribute || !ruseDefault.test( name ) ) {
|
// IE<8 needs the *property* name
|
elem.setAttribute( !getSetAttribute && jQuery.propFix[ name ] || name, name );
|
|
// Use defaultChecked and defaultSelected for oldIE
|
} else {
|
elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
|
}
|
|
return name;
|
}
|
};
|
|
// Retrieve booleans specially
|
jQuery.each( jQuery.expr.match.bool.source.match( /\w+/g ), function( i, name ) {
|
|
var getter = attrHandle[ name ] || jQuery.find.attr;
|
|
attrHandle[ name ] = getSetInput && getSetAttribute || !ruseDefault.test( name ) ?
|
function( elem, name, isXML ) {
|
var ret, handle;
|
if ( !isXML ) {
|
// Avoid an infinite loop by temporarily removing this function from the getter
|
handle = attrHandle[ name ];
|
attrHandle[ name ] = ret;
|
ret = getter( elem, name, isXML ) != null ?
|
name.toLowerCase() :
|
null;
|
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 || !getSetAttribute ) {
|
jQuery.attrHooks.value = {
|
set: function( elem, value, name ) {
|
if ( jQuery.nodeName( elem, "input" ) ) {
|
// Does not return so that setAttribute is also used
|
elem.defaultValue = value;
|
} else {
|
// Use nodeHook if defined (#1954); otherwise setAttribute is fine
|
return nodeHook && nodeHook.set( elem, value, name );
|
}
|
}
|
};
|
}
|
|
// IE6/7 do not support getting/setting some attributes with get/setAttribute
|
if ( !getSetAttribute ) {
|
|
// Use this for any attribute in IE6/7
|
// This fixes almost every IE6/7 issue
|
nodeHook = {
|
set: function( elem, value, name ) {
|
// Set the existing or create a new attribute node
|
var ret = elem.getAttributeNode( name );
|
if ( !ret ) {
|
elem.setAttributeNode(
|
(ret = elem.ownerDocument.createAttribute( name ))
|
);
|
}
|
|
ret.value = value += "";
|
|
// Break association with cloned elements by also using setAttribute (#9646)
|
if ( name === "value" || value === elem.getAttribute( name ) ) {
|
return value;
|
}
|
}
|
};
|
|
// Some attributes are constructed with empty-string values when not defined
|
attrHandle.id = attrHandle.name = attrHandle.coords =
|
function( elem, name, isXML ) {
|
var ret;
|
if ( !isXML ) {
|
return (ret = elem.getAttributeNode( name )) && ret.value !== "" ?
|
ret.value :
|
null;
|
}
|
};
|
|
// Fixing value retrieval on a button requires this module
|
jQuery.valHooks.button = {
|
get: function( elem, name ) {
|
var ret = elem.getAttributeNode( name );
|
if ( ret && ret.specified ) {
|
return ret.value;
|
}
|
},
|
set: nodeHook.set
|
};
|
|
// Set contenteditable to false on removals(#10429)
|
// Setting to empty string throws an error as an invalid value
|
jQuery.attrHooks.contenteditable = {
|
set: function( elem, value, name ) {
|
nodeHook.set( elem, value === "" ? false : value, name );
|
}
|
};
|
|
// 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 ] = {
|
set: function( elem, value ) {
|
if ( value === "" ) {
|
elem.setAttribute( name, "auto" );
|
return value;
|
}
|
}
|
};
|
});
|
}
|
|
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 + "" );
|
}
|
};
|
}
|
|
});
|