Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
156 changes: 50 additions & 106 deletions src/attributes/attr.js
Original file line number Diff line number Diff line change
@@ -1,16 +1,13 @@
define([
"../core",
"../var/rnotwhite",
"../core/access",
"./support",
"./val",
"../var/rnotwhite",
"../selector"
], function( jQuery, rnotwhite, access, support ) {
], function( jQuery, access, support, rnotwhite ) {

var boolHook,
attrHandle = jQuery.expr.attrHandle,
ruseDefault = /^(?:checked|selected)$/i,
getSetInput = support.input;
attrHandle = jQuery.expr.attrHandle;

jQuery.fn.extend({
attr: function( name, value ) {
Expand All @@ -26,10 +23,10 @@ jQuery.fn.extend({

jQuery.extend({
attr: function( elem, name, value ) {
var hooks, ret,
var ret, hooks,
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 ) {
return;
}
Expand All @@ -48,30 +45,43 @@ jQuery.extend({
}

if ( value !== undefined ) {

if ( value === null ) {
jQuery.removeAttr( elem, name );
return;
}

} else if ( hooks && "set" in hooks &&
(ret = hooks.set( elem, value, name )) !== undefined ) {

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 ) {
elem.setAttribute( name, value + "" );
return value;
}

if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
return ret;
}

} else {
ret = jQuery.find.attr( elem, name );
ret = jQuery.find.attr( elem, 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;
},

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;
}
}
}
},

Expand All @@ -81,116 +91,50 @@ jQuery.extend({
attrNames = value && value.match( rnotwhite );

if ( attrNames && elem.nodeType === 1 ) {
while ( (name = attrNames[i++]) ) {
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 || !ruseDefault.test( name ) ) {
elem[ propName ] = false;
// Support: IE<9
// Also clear defaultChecked/defaultSelected (if appropriate)
} else {
elem[ jQuery.camelCase( "default-" + name ) ] =
elem[ propName ] = false;
}
elem[ propName ] = false;
}

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 = {
set: function( elem, value, name ) {
if ( value === false ) {
// Remove boolean attributes when set to false
jQuery.removeAttr( elem, name );
} else if ( getSetInput || !ruseDefault.test( name ) ) {
elem.setAttribute( jQuery.propFix[ name ] || name, name );

} else {
// Support: IE<9
// Use defaultChecked and defaultSelected for oldIE
elem[ jQuery.camelCase( "default-" + name ) ] = elem[ name ] = true;
elem.setAttribute( name, name );
}

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 || !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 ) {
jQuery.attrHooks.value = {
set: function( elem, value ) {
if ( jQuery.nodeName( elem, "input" ) ) {
// Does not return so that setAttribute is also used
elem.defaultValue = value;
}
attrHandle[ 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;
};
}

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 + "" );
}
};
}
});

});
79 changes: 31 additions & 48 deletions src/attributes/prop.js
Original file line number Diff line number Diff line change
@@ -1,97 +1,80 @@
define([
"../core",
"../core/access",
"./support"
"./support",
"../selector"
], function( jQuery, access, support ) {

var rfocusable = /^(?:input|select|textarea|button|object)$/i,
rclickable = /^(?:a|area)$/i;
var rfocusable = /^(?:input|select|textarea|button)$/i;

jQuery.fn.extend({
prop: function( name, value ) {
return access( this, jQuery.prop, name, value, arguments.length > 1 );
},

removeProp: function( name ) {
name = jQuery.propFix[ name ] || name;
return this.each(function() {
// try/catch handles cases where IE balks (such as removing a property on window)
try {
this[ name ] = undefined;
delete this[ name ];
} catch ( e ) {}
delete this[ jQuery.propFix[ name ] || name ];
});
}
});

jQuery.extend({
propFix: {
"for": "htmlFor",
"class": "className"
},

prop: function( elem, name, value ) {
var ret, hooks, notxml,
var ret, hooks,
nType = elem.nodeType;

// don't get/set properties on text, comment and attribute nodes
if ( !elem || nType === 3 || nType === 8 || nType === 2 ) {
// Don't get/set properties on text, comment and attribute nodes
if ( nType === 3 || nType === 8 || nType === 2 ) {
return;
}

notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
if ( nType !== 1 || !jQuery.isXMLDoc( elem ) ) {

if ( notxml ) {
// Fix name and attach hooks
name = jQuery.propFix[ name ] || name;
hooks = jQuery.propHooks[ name ];
}

if ( value !== undefined ) {
return hooks && "set" in hooks &&
(ret = hooks.set( elem, value, name )) !== undefined ?
ret :
( elem[ name ] = value );

} else {
return hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== null ?
ret :
elem[ name ];
if ( hooks && "set" in hooks &&
( ret = hooks.set( elem, value, name ) ) !== undefined ) {
return ret;
}

return ( elem[ name ] = value );
}

if ( hooks && "get" in hooks && ( ret = hooks.get( elem, name ) ) !== null ) {
return ret;
}

return elem[ name ];
},

propHooks: {
tabIndex: {
get: function( elem ) {
// elem.tabIndex doesn't always return the
// correct value when it hasn't been explicitly set
// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
// Use proper attribute retrieval(#12072)
var tabindex = jQuery.find.attr( elem, "tabindex" );

return tabindex ?
parseInt( tabindex, 10 ) :
rfocusable.test( elem.nodeName ) ||
rclickable.test( elem.nodeName ) && elem.href ?
0 :
-1;
return elem.hasAttribute( "tabindex" ) ||
rfocusable.test( elem.nodeName ) || elem.href ?
elem.tabIndex :
-1;
}
}
},

propFix: {
"for": "htmlFor",
"class": "className"
}
});

if ( !support.optSelected ) {
jQuery.propHooks.selected = {
get: function( elem ) {
var parent = elem.parentNode;

if ( parent ) {
parent.selectedIndex;

// Make sure that it also works with optgroups, see #5701
if ( parent.parentNode ) {
parent.parentNode.selectedIndex;
}
if ( parent && parent.parentNode ) {
parent.parentNode.selectedIndex;
}
return null;
}
Expand Down