Very crude first pass at splitting apart the attr/prop logic. Also adding in attrHooks/propHooks. All of it is completely untested.
This commit is contained in:
parent
6c124d3dd4
commit
d4e4414451
|
@ -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({
|
||||||
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,104 +300,152 @@ 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;
|
|
||||||
}
|
} else {
|
||||||
}
|
// convert the value to a string (all browsers do this but IE) see #1070
|
||||||
|
value = "" + value;
|
||||||
|
|
||||||
|
elem.setAttribute( name, value );
|
||||||
|
|
||||||
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If applicable, access the attribute via the DOM 0 way
|
} else {
|
||||||
// 'in' checks fail in Blackberry 4.7 #6931
|
|
||||||
if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) {
|
|
||||||
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 ) {
|
if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem )) !== undefined ) {
|
||||||
if ( elem.nodeType === 1 ) {
|
return ret;
|
||||||
elem.removeAttribute( name );
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
elem[ name ] = value;
|
|
||||||
}
|
if ( !jQuery.hasAttr( elem, name ) ) {
|
||||||
|
return undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
// browsers index elements by id/name on forms, give priority to attributes.
|
var attr = elem.getAttribute( name );
|
||||||
if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) {
|
|
||||||
return elem.getAttributeNode( name ).nodeValue;
|
// 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 ));
|
||||||
|
},
|
||||||
|
|
||||||
|
attrHooks: {
|
||||||
|
type: {
|
||||||
|
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: {
|
||||||
var attributeNode = elem.getAttributeNode( "tabIndex" );
|
get: function( elem ) {
|
||||||
|
var attributeNode = elem.getAttributeNode( "tabIndex" );
|
||||||
|
|
||||||
return attributeNode && attributeNode.specified ?
|
return attributeNode && attributeNode.specified ?
|
||||||
attributeNode.value :
|
attributeNode.value :
|
||||||
rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
|
rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
|
||||||
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" ) {
|
|
||||||
if ( set ) {
|
|
||||||
elem.style.cssText = "" + value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return elem.style.cssText;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( set ) {
|
|
||||||
// convert the value to a string (all browsers do this but IE) see #1070
|
|
||||||
elem.setAttribute( name, "" + value );
|
|
||||||
}
|
|
||||||
|
|
||||||
// Ensure that missing attributes return undefined
|
|
||||||
// Blackberry 4.7 returns "" from getAttribute #6938
|
|
||||||
if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
|
|
||||||
var attr = !jQuery.support.hrefNormalized && notxml && special ?
|
|
||||||
// Some attributes require a special call on IE
|
|
||||||
elem.getAttribute( name, 2 ) :
|
|
||||||
elem.getAttribute( name );
|
|
||||||
|
|
||||||
// Non-existent attributes return null, we normalize to undefined
|
|
||||||
return attr === null ? undefined : attr;
|
|
||||||
}
|
}
|
||||||
// Handle everything which isn't a DOM element node
|
},
|
||||||
if ( set ) {
|
|
||||||
elem[ name ] = value;
|
propHooks: {}
|
||||||
}
|
|
||||||
return elem[ name ];
|
|
||||||
}
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// 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;
|
||||||
|
},
|
||||||
|
|
||||||
|
set: function( elem, value ) {
|
||||||
|
return (elem.style.cssText = "" + value);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// Safari mis-reports the default selected property of an option
|
||||||
|
// Accessing the parent's selectedIndex property fixes it
|
||||||
|
if ( !jQuery.support.optSelected ) {
|
||||||
|
jQuery.attrHooks.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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
})( jQuery );
|
})( jQuery );
|
||||||
|
|
Loading…
Reference in a new issue