Commit d4e44144 authored by jeresig's avatar jeresig

Very crude first pass at splitting apart the attr/prop logic. Also adding in...

Very crude first pass at splitting apart the attr/prop logic. Also adding in attrHooks/propHooks. All of it is completely untested.
parent 6c124d3d
...@@ -3,39 +3,38 @@ ...@@ -3,39 +3,38 @@
var rclass = /[\n\t\r]/g, var rclass = /[\n\t\r]/g,
rspaces = /\s+/, rspaces = /\s+/,
rreturn = /\r/g, rreturn = /\r/g,
rspecialurl = /^(?:href|src|style)$/,
rtype = /^(?:button|input)$/i, rtype = /^(?:button|input)$/i,
rfocusable = /^(?:button|input|object|select|textarea)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i,
rclickable = /^a(?:rea)?$/i, rclickable = /^a(?:rea)?$/i,
rradiocheck = /^(?:radio|checkbox)$/i; rradiocheck = /^(?:radio|checkbox)$/i;
jQuery.props = {
"for": "htmlFor",
"class": "className",
readonly: "readOnly",
maxlength: "maxLength",
cellspacing: "cellSpacing",
rowspan: "rowSpan",
colspan: "colSpan",
tabindex: "tabIndex",
usemap: "useMap",
frameborder: "frameBorder"
};
jQuery.fn.extend({ jQuery.fn.extend({
attr: function( name, value ) { attr: function( name, value ) {
return jQuery.access( this, name, value, true, jQuery.attr ); return jQuery.access( this, name, value, true, jQuery.attr );
}, },
removeAttr: function( name, fn ) { removeAttr: function( name ) {
return this.each(function(){ return this.each(function() {
jQuery.attr( this, name, "" );
if ( this.nodeType === 1 ) { if ( this.nodeType === 1 ) {
this.removeAttribute( name ); this.removeAttribute( name );
} }
}); });
}, },
prop: function( name, value ) {
return jQuery.access( this, name, value, true, jQuery.prop );
},
removeProp: function( 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 ) {}
});
},
addClass: function( value ) { addClass: function( value ) {
if ( jQuery.isFunction(value) ) { if ( jQuery.isFunction(value) ) {
return this.each(function(i) { return this.each(function(i) {
...@@ -276,6 +275,21 @@ jQuery.extend({ ...@@ -276,6 +275,21 @@ jQuery.extend({
offset: true offset: true
}, },
// TODO: Check to see if any of these are needed anymore?
// If not, it may be good to standardize on all-lowercase names instead
attrFix: {
"for": "htmlFor",
"class": "className",
readonly: "readOnly",
maxlength: "maxLength",
cellspacing: "cellSpacing",
rowspan: "rowSpan",
colspan: "colSpan",
tabindex: "tabIndex",
usemap: "useMap",
frameborder: "frameBorder"
},
attr: function( elem, name, value, pass ) { attr: function( elem, name, value, pass ) {
// don't get/set attributes on text, comment and attribute nodes // don't get/set attributes on text, comment and attribute nodes
if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) { if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) {
...@@ -286,59 +300,69 @@ jQuery.extend({ ...@@ -286,59 +300,69 @@ jQuery.extend({
return jQuery(elem)[name](value); return jQuery(elem)[name](value);
} }
var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), var ret,
// Whether we are setting (or getting) notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ),
set = value !== undefined; hooks;
// Try to normalize/fix the name // Try to normalize/fix the name
name = notxml && jQuery.props[ name ] || name; name = notxml && jQuery.attrFix[ name ] || name;
// Only do all the following if this is a node (faster for style) hooks = jQuery.attrHooks[ name ];
if ( elem.nodeType === 1 ) {
// These attributes require special treatment
var special = rspecialurl.test( name );
// Safari mis-reports the default selected property of an option if ( value !== undefined ) {
// Accessing the parent's selectedIndex property fixes it
if ( name === "selected" && !jQuery.support.optSelected ) {
var parent = elem.parentNode;
if ( parent ) {
parent.selectedIndex;
// Make sure that it also works with optgroups, see #5701 if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value )) !== undefined ) {
if ( parent.parentNode ) { return ret;
parent.parentNode.selectedIndex;
}
}
}
// If applicable, access the attribute via the DOM 0 way } else {
// 'in' checks fail in Blackberry 4.7 #6931 // convert the value to a string (all browsers do this but IE) see #1070
if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) { value = "" + value;
if ( set ) {
// We can't allow the type property to be changed (since it causes problems in IE)
if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) {
jQuery.error( "type property can't be changed" );
}
if ( value === null ) { elem.setAttribute( name, value );
if ( elem.nodeType === 1 ) {
elem.removeAttribute( name ); return value;
} }
} else { } else {
elem[ name ] = value;
if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem )) !== undefined ) {
return ret;
} else {
if ( !jQuery.hasAttr( elem, name ) ) {
return undefined;
}
var attr = elem.getAttribute( name );
// Non-existent attributes return null, we normalize to undefined
return attr === null ?
undefined :
attr;
} }
} }
},
hasAttr: function( elem, name ) {
// Blackberry 4.7 returns "" from getAttribute #6938
return elem.attributes[ name ] || (elem.hasAttribute && elem.hasAttribute( name ));
},
// browsers index elements by id/name on forms, give priority to attributes. attrHooks: {
if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { type: {
return elem.getAttributeNode( name ).nodeValue; set: function( elem, value ) {
// We can't allow the type property to be changed (since it causes problems in IE)
if ( rtype.test( elem.nodeName ) && elem.parentNode ) {
jQuery.error( "type property can't be changed" );
} }
}
},
// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set // 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/ // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
if ( name === "tabIndex" ) { tabIndex: {
get: function( elem ) {
var attributeNode = elem.getAttributeNode( "tabIndex" ); var attributeNode = elem.getAttributeNode( "tabIndex" );
return attributeNode && attributeNode.specified ? return attributeNode && attributeNode.specified ?
...@@ -347,43 +371,81 @@ jQuery.extend({ ...@@ -347,43 +371,81 @@ jQuery.extend({
0 : 0 :
undefined; undefined;
} }
}
},
// TODO: Check to see if we really need any here.
propFix: {},
prop: function( elem, name, value ) {
var ret, hooks;
// Try to normalize/fix the name
name = notxml && jQuery.propFix[ name ] || name;
hooks = jQuery.propHooks[ name ];
if ( value !== undefined ) {
if ( hooks && "set" in hooks && (ret = hooks.set( elem, value )) !== undefined ) {
return ret;
} else {
return (elem[ name ] = value);
}
} else {
if ( hooks && "get" in hooks && (ret = hooks.get( elem )) !== undefined ) {
return ret;
} else {
return elem[ name ]; return elem[ name ];
} }
}
},
if ( !jQuery.support.style && notxml && name === "style" ) { propHooks: {}
if ( set ) { });
elem.style.cssText = "" + value;
// Some attributes require a special call on IE
if ( !jQuery.support.hrefNormalized ) {
jQuery.each([ "href", "src", "style" ], function( i, name ) {
jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], {
get: function( elem ) {
return elem.getAttribute( name, 2 );
} }
});
});
}
if ( !jQuery.support.style ) {
jQuery.attrHooks.style = {
get: function( elem ) {
return elem.style.cssText; return elem.style.cssText;
} },
if ( set ) { set: function( elem, value ) {
// convert the value to a string (all browsers do this but IE) see #1070 return (elem.style.cssText = "" + value);
elem.setAttribute( name, "" + value );
} }
};
}
// Ensure that missing attributes return undefined // Safari mis-reports the default selected property of an option
// Blackberry 4.7 returns "" from getAttribute #6938 // Accessing the parent's selectedIndex property fixes it
if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) { if ( !jQuery.support.optSelected ) {
return undefined; jQuery.attrHooks.selected = {
} get: function( elem ) {
var parent = elem.parentNode;
var attr = !jQuery.support.hrefNormalized && notxml && special ? if ( parent ) {
// Some attributes require a special call on IE parent.selectedIndex;
elem.getAttribute( name, 2 ) :
elem.getAttribute( name );
// Non-existent attributes return null, we normalize to undefined // Make sure that it also works with optgroups, see #5701
return attr === null ? undefined : attr; if ( parent.parentNode ) {
parent.parentNode.selectedIndex;
} }
// Handle everything which isn't a DOM element node
if ( set ) {
elem[ name ] = value;
} }
return elem[ name ];
} }
}); };
}
})( jQuery ); })( jQuery );
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