Skip to content

Commit 8c2cb49

Browse files
committed
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.
1 parent fd4ee2a commit 8c2cb49

File tree

2 files changed

+40
-46
lines changed

2 files changed

+40
-46
lines changed

src/attributes.js

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ var rclass = /[\n\t\r]/g,
88
rclickable = /^a(?:rea)?$/i,
99
rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i,
1010
rinvalidChar = /\:|^on/,
11-
formHook, boolHook;
11+
nodeHook, boolHook;
1212

1313
jQuery.fn.extend({
1414
attr: function( name, value ) {
@@ -326,14 +326,11 @@ jQuery.extend({
326326
if ( !hooks ) {
327327
// Use boolHook for boolean attributes
328328
if ( rboolean.test( name ) ) {
329-
330329
hooks = boolHook;
331330

332-
// Use formHook for forms and if the name contains certain characters
333-
} else if ( formHook && name !== "className" &&
334-
(jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) {
335-
336-
hooks = formHook;
331+
// Use nodeHook if available( IE6/7 )
332+
} else if ( nodeHook ) {
333+
hooks = nodeHook;
337334
}
338335
}
339336
}
@@ -406,19 +403,19 @@ jQuery.extend({
406403
}
407404
},
408405
// Use the value property for back compat
409-
// Use the formHook for button elements in IE6/7 (#1954)
406+
// Use the nodeHook for button elements in IE6/7 (#1954)
410407
value: {
411408
get: function( elem, name ) {
412-
if ( formHook && jQuery.nodeName( elem, "button" ) ) {
413-
return formHook.get( elem, name );
409+
if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
410+
return nodeHook.get( elem, name );
414411
}
415412
return name in elem ?
416413
elem.value :
417414
null;
418415
},
419416
set: function( elem, value, name ) {
420-
if ( formHook && jQuery.nodeName( elem, "button" ) ) {
421-
return formHook.set( elem, value, name );
417+
if ( nodeHook && jQuery.nodeName( elem, "button" ) ) {
418+
return nodeHook.set( elem, value, name );
422419
}
423420
// Does not return so that setAttribute is also used
424421
elem.value = value;
@@ -481,7 +478,7 @@ jQuery.extend({
481478
get: function( elem ) {
482479
// elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set
483480
// http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/
484-
var attributeNode = elem.getAttributeNode("tabIndex");
481+
var attributeNode = elem.getAttributeNode("tabindex");
485482

486483
return attributeNode && attributeNode.specified ?
487484
parseInt( attributeNode.value, 10 ) :
@@ -528,12 +525,10 @@ boolHook = {
528525

529526
// IE6/7 do not support getting/setting some attributes with get/setAttribute
530527
if ( !jQuery.support.getSetAttribute ) {
531-
532-
// propFix is more comprehensive and contains all fixes
533-
jQuery.attrFix = jQuery.propFix;
534528

535-
// Use this for any attribute on a form in IE6/7
536-
formHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = {
529+
// Use this for any attribute in IE6/7
530+
// This fixes almost every IE6/7 issue
531+
nodeHook = jQuery.valHooks.button = {
537532
get: function( elem, name ) {
538533
var ret;
539534
ret = elem.getAttributeNode( name );
@@ -543,13 +538,13 @@ if ( !jQuery.support.getSetAttribute ) {
543538
undefined;
544539
},
545540
set: function( elem, value, name ) {
546-
// Check form objects in IE (multiple bugs related)
547-
// Only use nodeValue if the attribute node exists on the form
541+
// Set the existing or create a new attribute node
548542
var ret = elem.getAttributeNode( name );
549-
if ( ret ) {
550-
ret.nodeValue = value;
551-
return value;
543+
if ( !ret ) {
544+
ret = document.createAttribute( name );
545+
elem.setAttributeNode( ret );
552546
}
547+
return (ret.nodeValue = value + "");
553548
}
554549
};
555550

test/unit/attributes.js

Lines changed: 22 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,11 @@ test("jQuery.attrFix/jQuery.propFix integrity test", function() {
2424
usemap: "useMap",
2525
frameborder: "frameBorder",
2626
contenteditable: "contentEditable"
27-
},
28-
propsShouldBe;
29-
30-
if ( !jQuery.support.getSetAttribute ) {
31-
propsShouldBe = props;
32-
} else {
33-
propsShouldBe = {
34-
tabindex: "tabIndex"
3527
};
36-
}
28+
29+
var propsShouldBe = {
30+
tabindex: "tabIndex"
31+
};
3732

3833
deepEqual(propsShouldBe, jQuery.attrFix, "jQuery.attrFix passes integrity check");
3934
deepEqual(props, jQuery.propFix, "jQuery.propFix passes integrity check");
@@ -162,7 +157,7 @@ test("attr(Hash)", function() {
162157
});
163158

164159
test("attr(String, Object)", function() {
165-
expect(73);
160+
expect(75);
166161

167162
var div = jQuery("div").attr("foo", "bar"),
168163
fail = false;
@@ -244,9 +239,13 @@ test("attr(String, Object)", function() {
244239
equal( $details.attr("open"), "open", "open attribute presense indicates true" );
245240
equal( $details.attr("open", false).attr("open"), undefined, "Setting open attribute to false removes it" );
246241

247-
equals( $text.attr("data-something", true).data("something"), true, "Setting data attributes are not affected by boolean settings");
248-
equals( $text.attr("data-another", false).data("another"), false, "Setting data attributes are not affected by boolean settings" );
249-
equals( $text.attr("aria-disabled", false).attr("aria-disabled"), "false", "Setting aria attributes are not affected by boolean settings");
242+
$text.attr("data-something", true);
243+
equal( $text.attr("data-something"), "true", "Set data attributes");
244+
equal( $text.data("something"), true, "Setting data attributes are not affected by boolean settings");
245+
$text.attr("data-another", false);
246+
equal( $text.attr("data-another"), "false", "Set data attributes");
247+
equal( $text.data("another"), false, "Setting data attributes are not affected by boolean settings" );
248+
equal( $text.attr("aria-disabled", false).attr("aria-disabled"), "false", "Setting aria attributes are not affected by boolean settings");
250249
$text.removeData("something").removeData("another").removeAttr("aria-disabled");
251250

252251
jQuery("#foo").attr("contenteditable", true);
@@ -1032,43 +1031,43 @@ test("toggleClass(Fucntion[, boolean]) with incoming value", function() {
10321031
ok( !e.is(".test"), "Assert class not present" );
10331032

10341033
e.toggleClass(function(i, val) {
1035-
equals( val, old, "Make sure the incoming value is correct." );
1034+
equal( old, val, "Make sure the incoming value is correct." );
10361035
return "test";
10371036
});
10381037
ok( e.is(".test"), "Assert class present" );
10391038

10401039
old = e.attr("class");
10411040

10421041
e.toggleClass(function(i, val) {
1043-
equals( val, old, "Make sure the incoming value is correct." );
1042+
equal( old, val, "Make sure the incoming value is correct." );
10441043
return "test";
10451044
});
10461045
ok( !e.is(".test"), "Assert class not present" );
10471046

1048-
old = e.attr("class");
1047+
old = e.attr("class") || "";
10491048

10501049
// class name with a boolean
10511050
e.toggleClass(function(i, val, state) {
1052-
equals( val, old, "Make sure the incoming value is correct." );
1053-
equals( state, false, "Make sure that the state is passed in." );
1051+
equal( old, val, "Make sure the incoming value is correct." );
1052+
equal( state, false, "Make sure that the state is passed in." );
10541053
return "test";
10551054
}, false );
10561055
ok( !e.is(".test"), "Assert class not present" );
10571056

1058-
old = e.attr("class");
1057+
old = e.attr("class") || "";
10591058

10601059
e.toggleClass(function(i, val, state) {
1061-
equals( val, old, "Make sure the incoming value is correct." );
1062-
equals( state, true, "Make sure that the state is passed in." );
1060+
equal( old, val, "Make sure the incoming value is correct." );
1061+
equal( state, true, "Make sure that the state is passed in." );
10631062
return "test";
10641063
}, true );
10651064
ok( e.is(".test"), "Assert class present" );
10661065

10671066
old = e.attr("class");
10681067

10691068
e.toggleClass(function(i, val, state) {
1070-
equals( val, old, "Make sure the incoming value is correct." );
1071-
equals( state, false, "Make sure that the state is passed in." );
1069+
equal( old, val, "Make sure the incoming value is correct." );
1070+
equal( state, false, "Make sure that the state is passed in." );
10721071
return "test";
10731072
}, false );
10741073
ok( !e.is(".test"), "Assert class not present" );

0 commit comments

Comments
 (0)