mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Fix #6562, tighten up the special code for form objects, add name attrHook for IE6/7, and don't check for undefined with getting hook'd attr
This commit is contained in:
parent
102053abd8
commit
9e05a0a37f
@ -275,7 +275,10 @@ jQuery.extend({
|
|||||||
offset: true
|
offset: true
|
||||||
},
|
},
|
||||||
|
|
||||||
attrFix: {},
|
attrFix: {
|
||||||
|
// Always normalize to ensure hook usage
|
||||||
|
tabindex: "tabIndex"
|
||||||
|
},
|
||||||
|
|
||||||
attr: function( elem, name, value, pass ) {
|
attr: function( elem, name, value, pass ) {
|
||||||
var nType = elem.nodeType;
|
var nType = elem.nodeType;
|
||||||
@ -290,7 +293,8 @@ jQuery.extend({
|
|||||||
}
|
}
|
||||||
|
|
||||||
var ret, hooks,
|
var ret, hooks,
|
||||||
notxml = nType !== 1 || !jQuery.isXMLDoc( elem );
|
notxml = nType !== 1 || !jQuery.isXMLDoc( elem ),
|
||||||
|
isFormObjects = !jQuery.support.getSetAttribute && elem.nodeName === "FORM";
|
||||||
|
|
||||||
// Normalize the name if needed
|
// Normalize the name if needed
|
||||||
name = notxml && jQuery.attrFix[ name ] || name;
|
name = notxml && jQuery.attrFix[ name ] || name;
|
||||||
@ -306,18 +310,31 @@ jQuery.extend({
|
|||||||
jQuery.removeAttr( elem, name );
|
jQuery.removeAttr( elem, name );
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Check form objects in IE (multiple bugs related)
|
||||||
|
if ( isFormObjects ) {
|
||||||
|
elem.getAttributeNode( name ).nodeValue = value;
|
||||||
} else {
|
} else {
|
||||||
elem.setAttribute( name, value );
|
elem.setAttribute( name, value );
|
||||||
|
}
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if ( hooks && "get" in hooks && notxml && ((ret = hooks.get( elem )) !== undefined || name === "tabIndex") ) {
|
if ( hooks && "get" in hooks && notxml ) {
|
||||||
return ret;
|
return hooks.get( elem );
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// Check form objects in IE (multiple bugs related)
|
||||||
|
if ( isFormObjects ) {
|
||||||
|
// Returns undefined for empty string, which is the blank nodeValue in IE
|
||||||
|
ret = elem.getAttributeNode( name ).nodeValue || undefined;
|
||||||
} else {
|
} else {
|
||||||
ret = elem.getAttribute( name );
|
ret = elem.getAttribute( name );
|
||||||
|
}
|
||||||
|
|
||||||
// Non-existent attributes return null, we normalize to undefined
|
// Non-existent attributes return null, we normalize to undefined
|
||||||
// Instead of checking for null, we check for typeof object to catch inputs in IE6/7. Bug #7472
|
// Instead of checking for null, we check for typeof object to catch inputs in IE6/7. Bug #7472
|
||||||
@ -334,13 +351,9 @@ jQuery.extend({
|
|||||||
if ( jQuery.support.getSetAttribute ) {
|
if ( jQuery.support.getSetAttribute ) {
|
||||||
elem.removeAttribute( name );
|
elem.removeAttribute( name );
|
||||||
} else {
|
} else {
|
||||||
// set property to null if getSetAttribute not supported (IE6-7)
|
// use DOM level 1 if getSetAttribute not supported (IE6-7)
|
||||||
// setting className to null makes the class "null"
|
elem.setAttribute( name, "" ); // Set to default empty string
|
||||||
if ( name === "className" ) {
|
elem.removeAttributeNode( elem.getAttributeNode( name ) );
|
||||||
elem[ name ] = "";
|
|
||||||
} else {
|
|
||||||
elem.setAttribute( name, null );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -352,6 +365,19 @@ jQuery.extend({
|
|||||||
jQuery.error( "type property can't be changed" );
|
jQuery.error( "type property can't be changed" );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
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/
|
||||||
|
var attributeNode = elem.getAttributeNode("tabIndex");
|
||||||
|
|
||||||
|
return attributeNode && attributeNode.specified ?
|
||||||
|
parseInt( attributeNode.value, 10 ) :
|
||||||
|
rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
|
||||||
|
0 :
|
||||||
|
undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -404,23 +430,15 @@ if ( !jQuery.support.getSetAttribute ) {
|
|||||||
cellspacing: "cellSpacing",
|
cellspacing: "cellSpacing",
|
||||||
rowspan: "rowSpan",
|
rowspan: "rowSpan",
|
||||||
colspan: "colSpan",
|
colspan: "colSpan",
|
||||||
tabindex: "tabIndex",
|
|
||||||
usemap: "useMap",
|
usemap: "useMap",
|
||||||
frameborder: "frameBorder"
|
frameborder: "frameBorder"
|
||||||
});
|
});
|
||||||
|
|
||||||
// Action attribute in ie6/7 returns form objects
|
// Name attribute will not get removed in browsers that do not support getSetAttribute
|
||||||
jQuery.attrHooks.action = {
|
// Return undefined on empty string or null
|
||||||
get: function( elem ) {
|
jQuery.attrHooks.name = {
|
||||||
return elem.nodeName === "FORM" ?
|
get: function( elem, value ) {
|
||||||
elem.getAttributeNode("action").nodeValue :
|
return elem.getAttributeNode("name").nodeValue || undefined;
|
||||||
elem.getAttribute("action");
|
|
||||||
},
|
|
||||||
set: function( elem, value ) {
|
|
||||||
elem.nodeName === "FORM" ?
|
|
||||||
elem.getAttributeNode("action").nodeValue = value :
|
|
||||||
elem.setAttribute("action", value);
|
|
||||||
return value;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -442,20 +460,6 @@ jQuery.each([ "selected", "checked", "readonly", "disabled" ], function( i, name
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
// 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/
|
|
||||||
jQuery.attrHooks[ jQuery.attrFix.tabindex || "tabindex" ] = {
|
|
||||||
get: function( elem ) {
|
|
||||||
var attributeNode = elem.getAttributeNode("tabIndex");
|
|
||||||
|
|
||||||
return attributeNode && attributeNode.specified ?
|
|
||||||
parseInt( attributeNode.value, 10 ) :
|
|
||||||
rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ?
|
|
||||||
0 :
|
|
||||||
undefined;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// Some attributes require a special call on IE
|
// Some attributes require a special call on IE
|
||||||
if ( !jQuery.support.hrefNormalized ) {
|
if ( !jQuery.support.hrefNormalized ) {
|
||||||
jQuery.each([ "href", "src", "style" ], function( i, name ) {
|
jQuery.each([ "href", "src", "style" ], function( i, name ) {
|
||||||
|
@ -203,7 +203,8 @@ Z</textarea>
|
|||||||
<select name="D4" disabled="disabled">
|
<select name="D4" disabled="disabled">
|
||||||
<option selected="selected" value="NO">NO</option>
|
<option selected="selected" value="NO">NO</option>
|
||||||
</select>
|
</select>
|
||||||
<input name="id">
|
<input name="id" />
|
||||||
|
<input id="target" name="target" />
|
||||||
</form>
|
</form>
|
||||||
<div id="moretests">
|
<div id="moretests">
|
||||||
<form>
|
<form>
|
||||||
|
@ -3,7 +3,7 @@ module("attributes", { teardown: moduleTeardown });
|
|||||||
var bareObj = function(value) { return value; };
|
var bareObj = function(value) { return value; };
|
||||||
var functionReturningObj = function(value) { return (function() { return value; }); };
|
var functionReturningObj = function(value) { return (function() { return value; }); };
|
||||||
|
|
||||||
if ( !jQuery.support.getSetAttribute ) {
|
|
||||||
test("jQuery.attrFix integrity test", function() {
|
test("jQuery.attrFix integrity test", function() {
|
||||||
expect(1);
|
expect(1);
|
||||||
|
|
||||||
@ -11,7 +11,10 @@ if ( !jQuery.support.getSetAttribute ) {
|
|||||||
// Ensure that accidental or erroneous property
|
// Ensure that accidental or erroneous property
|
||||||
// overwrites don't occur
|
// overwrites don't occur
|
||||||
// This is simply for better code coverage and future proofing.
|
// This is simply for better code coverage and future proofing.
|
||||||
var propsShouldBe = {
|
var propsShouldBe;
|
||||||
|
if ( !jQuery.support.getSetAttribute ) {
|
||||||
|
propsShouldBe = {
|
||||||
|
tabindex: "tabIndex",
|
||||||
"for": "htmlFor",
|
"for": "htmlFor",
|
||||||
"class": "className",
|
"class": "className",
|
||||||
readonly: "readOnly",
|
readonly: "readOnly",
|
||||||
@ -19,14 +22,17 @@ if ( !jQuery.support.getSetAttribute ) {
|
|||||||
cellspacing: "cellSpacing",
|
cellspacing: "cellSpacing",
|
||||||
rowspan: "rowSpan",
|
rowspan: "rowSpan",
|
||||||
colspan: "colSpan",
|
colspan: "colSpan",
|
||||||
tabindex: "tabIndex",
|
|
||||||
usemap: "useMap",
|
usemap: "useMap",
|
||||||
frameborder: "frameBorder"
|
frameborder: "frameBorder"
|
||||||
};
|
};
|
||||||
|
} else {
|
||||||
|
propsShouldBe = {
|
||||||
|
tabindex: "tabIndex"
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
same(propsShouldBe, jQuery.attrFix, "jQuery.attrFix passes integrity check");
|
same(propsShouldBe, jQuery.attrFix, "jQuery.attrFix passes integrity check");
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
test("prop(String, Object)", function() {
|
test("prop(String, Object)", function() {
|
||||||
expect(19);
|
expect(19);
|
||||||
@ -69,7 +75,7 @@ test("prop(String, Object)", function() {
|
|||||||
});
|
});
|
||||||
|
|
||||||
test("attr(String)", function() {
|
test("attr(String)", function() {
|
||||||
expect(22);
|
expect(24);
|
||||||
|
|
||||||
equals( jQuery('#text1').attr('type'), "text", 'Check for type attribute' );
|
equals( jQuery('#text1').attr('type'), "text", 'Check for type attribute' );
|
||||||
equals( jQuery('#radio1').attr('type'), "radio", 'Check for type attribute' );
|
equals( jQuery('#radio1').attr('type'), "radio", 'Check for type attribute' );
|
||||||
@ -84,7 +90,9 @@ test("attr(String)", function() {
|
|||||||
ok( jQuery('#form').attr('action').indexOf("formaction") >= 0, 'Check for action attribute' );
|
ok( jQuery('#form').attr('action').indexOf("formaction") >= 0, 'Check for action attribute' );
|
||||||
// [7472] & [3113] (form contains an input with name="action" or name="id")
|
// [7472] & [3113] (form contains an input with name="action" or name="id")
|
||||||
equals( jQuery('#form').attr('action','newformaction').attr('action'), 'newformaction', 'Check that action attribute was changed' );
|
equals( jQuery('#form').attr('action','newformaction').attr('action'), 'newformaction', 'Check that action attribute was changed' );
|
||||||
equals( jQuery('#testForm').removeAttr('id').attr('id'), undefined, 'Test that id does not equal the input with name=id after id is removed [#7472]' );
|
equals( jQuery('#testForm').attr('target'), undefined, 'Retrieving target does not equal the input with name=target' );
|
||||||
|
equals( jQuery('#testForm').attr('target', 'newTarget').attr('target'), 'newTarget', 'Set target successfully on a form' );
|
||||||
|
equals( jQuery('#testForm').removeAttr('id').attr('id'), undefined, 'Retrieving id does not equal the input with name=id after id is removed [#7472]' );
|
||||||
|
|
||||||
equals( jQuery('#text1').attr('maxlength'), '30', 'Check for maxlength attribute' );
|
equals( jQuery('#text1').attr('maxlength'), '30', 'Check for maxlength attribute' );
|
||||||
equals( jQuery('#text1').attr('maxLength'), '30', 'Check for maxLength attribute' );
|
equals( jQuery('#text1').attr('maxLength'), '30', 'Check for maxLength attribute' );
|
||||||
|
Loading…
Reference in New Issue
Block a user