Commit 8c2cb499 authored by timmywil's avatar timmywil

Now using getAttributeNode in all attribute cases in IE6/7, which normalizes...

Now using getAttributeNode in all attribute cases in IE6/7, which normalizes attribute behaviors across browsers, is less hacky, and shortens the attribute code. Fixes #9980.
parent fd4ee2a3
...@@ -8,7 +8,7 @@ var rclass = /[\n\t\r]/g, ...@@ -8,7 +8,7 @@ var rclass = /[\n\t\r]/g,
rclickable = /^a(?:rea)?$/i, rclickable = /^a(?:rea)?$/i,
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
rinvalidChar = /\:|^on/, rinvalidChar = /\:|^on/,
formHook, boolHook; nodeHook, boolHook;
jQuery.fn.extend({ jQuery.fn.extend({
attr: function( name, value ) { attr: function( name, value ) {
...@@ -326,14 +326,11 @@ jQuery.extend({ ...@@ -326,14 +326,11 @@ jQuery.extend({
if ( !hooks ) { if ( !hooks ) {
// Use boolHook for boolean attributes // Use boolHook for boolean attributes
if ( rboolean.test( name ) ) { if ( rboolean.test( name ) ) {
hooks = boolHook; hooks = boolHook;
// Use formHook for forms and if the name contains certain characters // Use nodeHook if available( IE6/7 )
} else if ( formHook && name !== "className" && } else if ( nodeHook ) {
(jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) { hooks = nodeHook;
hooks = formHook;
} }
} }
} }
...@@ -406,19 +403,19 @@ jQuery.extend({ ...@@ -406,19 +403,19 @@ jQuery.extend({
} }
}, },
// Use the value property for back compat // Use the value property for back compat
// Use the formHook for button elements in IE6/7 (#1954) // Use the nodeHook for button elements in IE6/7 (#1954)
value: { value: {
get: function( elem, name ) { get: function( elem, name ) {
if ( formHook && jQuery.nodeName( elem, "button" ) ) { if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
return formHook.get( elem, name ); return nodeHook.get( elem, name );
} }
return name in elem ? return name in elem ?
elem.value : elem.value :
null; null;
}, },
set: function( elem, value, name ) { set: function( elem, value, name ) {
if ( formHook && jQuery.nodeName( elem, "button" ) ) { if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
return formHook.set( elem, value, name ); return nodeHook.set( elem, value, name );
} }
// Does not return so that setAttribute is also used // Does not return so that setAttribute is also used
elem.value = value; elem.value = value;
...@@ -481,7 +478,7 @@ jQuery.extend({ ...@@ -481,7 +478,7 @@ jQuery.extend({
get: function( elem ) { get: function( elem ) {
// 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/
var attributeNode = elem.getAttributeNode("tabIndex"); var attributeNode = elem.getAttributeNode("tabindex");
return attributeNode && attributeNode.specified ? return attributeNode && attributeNode.specified ?
parseInt( attributeNode.value, 10 ) : parseInt( attributeNode.value, 10 ) :
...@@ -528,12 +525,10 @@ boolHook = { ...@@ -528,12 +525,10 @@ boolHook = {
// IE6/7 do not support getting/setting some attributes with get/setAttribute // IE6/7 do not support getting/setting some attributes with get/setAttribute
if ( !jQuery.support.getSetAttribute ) { if ( !jQuery.support.getSetAttribute ) {
// propFix is more comprehensive and contains all fixes
jQuery.attrFix = jQuery.propFix;
// Use this for any attribute on a form in IE6/7 // Use this for any attribute in IE6/7
formHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = { // This fixes almost every IE6/7 issue
nodeHook = jQuery.valHooks.button = {
get: function( elem, name ) { get: function( elem, name ) {
var ret; var ret;
ret = elem.getAttributeNode( name ); ret = elem.getAttributeNode( name );
...@@ -543,13 +538,13 @@ if ( !jQuery.support.getSetAttribute ) { ...@@ -543,13 +538,13 @@ if ( !jQuery.support.getSetAttribute ) {
undefined; undefined;
}, },
set: function( elem, value, name ) { set: function( elem, value, name ) {
// Check form objects in IE (multiple bugs related) // Set the existing or create a new attribute node
// Only use nodeValue if the attribute node exists on the form
var ret = elem.getAttributeNode( name ); var ret = elem.getAttributeNode( name );
if ( ret ) { if ( !ret ) {
ret.nodeValue = value; ret = document.createAttribute( name );
return value; elem.setAttributeNode( ret );
} }
return (ret.nodeValue = value + "");
} }
}; };
......
...@@ -24,16 +24,11 @@ test("jQuery.attrFix/jQuery.propFix integrity test", function() { ...@@ -24,16 +24,11 @@ test("jQuery.attrFix/jQuery.propFix integrity test", function() {
usemap: "useMap", usemap: "useMap",
frameborder: "frameBorder", frameborder: "frameBorder",
contenteditable: "contentEditable" contenteditable: "contentEditable"
},
propsShouldBe;
if ( !jQuery.support.getSetAttribute ) {
propsShouldBe = props;
} else {
propsShouldBe = {
tabindex: "tabIndex"
}; };
}
var propsShouldBe = {
tabindex: "tabIndex"
};
deepEqual(propsShouldBe, jQuery.attrFix, "jQuery.attrFix passes integrity check"); deepEqual(propsShouldBe, jQuery.attrFix, "jQuery.attrFix passes integrity check");
deepEqual(props, jQuery.propFix, "jQuery.propFix passes integrity check"); deepEqual(props, jQuery.propFix, "jQuery.propFix passes integrity check");
...@@ -162,7 +157,7 @@ test("attr(Hash)", function() { ...@@ -162,7 +157,7 @@ test("attr(Hash)", function() {
}); });
test("attr(String, Object)", function() { test("attr(String, Object)", function() {
expect(73); expect(75);
var div = jQuery("div").attr("foo", "bar"), var div = jQuery("div").attr("foo", "bar"),
fail = false; fail = false;
...@@ -244,9 +239,13 @@ test("attr(String, Object)", function() { ...@@ -244,9 +239,13 @@ test("attr(String, Object)", function() {
equal( $details.attr("open"), "open", "open attribute presense indicates true" ); equal( $details.attr("open"), "open", "open attribute presense indicates true" );
equal( $details.attr("open", false).attr("open"), undefined, "Setting open attribute to false removes it" ); equal( $details.attr("open", false).attr("open"), undefined, "Setting open attribute to false removes it" );
equals( $text.attr("data-something", true).data("something"), true, "Setting data attributes are not affected by boolean settings"); $text.attr("data-something", true);
equals( $text.attr("data-another", false).data("another"), false, "Setting data attributes are not affected by boolean settings" ); equal( $text.attr("data-something"), "true", "Set data attributes");
equals( $text.attr("aria-disabled", false).attr("aria-disabled"), "false", "Setting aria attributes are not affected by boolean settings"); equal( $text.data("something"), true, "Setting data attributes are not affected by boolean settings");
$text.attr("data-another", false);
equal( $text.attr("data-another"), "false", "Set data attributes");
equal( $text.data("another"), false, "Setting data attributes are not affected by boolean settings" );
equal( $text.attr("aria-disabled", false).attr("aria-disabled"), "false", "Setting aria attributes are not affected by boolean settings");
$text.removeData("something").removeData("another").removeAttr("aria-disabled"); $text.removeData("something").removeData("another").removeAttr("aria-disabled");
jQuery("#foo").attr("contenteditable", true); jQuery("#foo").attr("contenteditable", true);
...@@ -1032,7 +1031,7 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() { ...@@ -1032,7 +1031,7 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() {
ok( !e.is(".test"), "Assert class not present" ); ok( !e.is(".test"), "Assert class not present" );
e.toggleClass(function(i, val) { e.toggleClass(function(i, val) {
equals( val, old, "Make sure the incoming value is correct." ); equal( old, val, "Make sure the incoming value is correct." );
return "test"; return "test";
}); });
ok( e.is(".test"), "Assert class present" ); ok( e.is(".test"), "Assert class present" );
...@@ -1040,26 +1039,26 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() { ...@@ -1040,26 +1039,26 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() {
old = e.attr("class"); old = e.attr("class");
e.toggleClass(function(i, val) { e.toggleClass(function(i, val) {
equals( val, old, "Make sure the incoming value is correct." ); equal( old, val, "Make sure the incoming value is correct." );
return "test"; return "test";
}); });
ok( !e.is(".test"), "Assert class not present" ); ok( !e.is(".test"), "Assert class not present" );
old = e.attr("class"); old = e.attr("class") || "";
// class name with a boolean // class name with a boolean
e.toggleClass(function(i, val, state) { e.toggleClass(function(i, val, state) {
equals( val, old, "Make sure the incoming value is correct." ); equal( old, val, "Make sure the incoming value is correct." );
equals( state, false, "Make sure that the state is passed in." ); equal( state, false, "Make sure that the state is passed in." );
return "test"; return "test";
}, false ); }, false );
ok( !e.is(".test"), "Assert class not present" ); ok( !e.is(".test"), "Assert class not present" );
old = e.attr("class"); old = e.attr("class") || "";
e.toggleClass(function(i, val, state) { e.toggleClass(function(i, val, state) {
equals( val, old, "Make sure the incoming value is correct." ); equal( old, val, "Make sure the incoming value is correct." );
equals( state, true, "Make sure that the state is passed in." ); equal( state, true, "Make sure that the state is passed in." );
return "test"; return "test";
}, true ); }, true );
ok( e.is(".test"), "Assert class present" ); ok( e.is(".test"), "Assert class present" );
...@@ -1067,8 +1066,8 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() { ...@@ -1067,8 +1066,8 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() {
old = e.attr("class"); old = e.attr("class");
e.toggleClass(function(i, val, state) { e.toggleClass(function(i, val, state) {
equals( val, old, "Make sure the incoming value is correct." ); equal( old, val, "Make sure the incoming value is correct." );
equals( state, false, "Make sure that the state is passed in." ); equal( state, false, "Make sure that the state is passed in." );
return "test"; return "test";
}, false ); }, false );
ok( !e.is(".test"), "Assert class not present" ); ok( !e.is(".test"), "Assert class not present" );
......
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