From a9d9f8c5422f171d9c451385fcfd7ed1661ec514 Mon Sep 17 00:00:00 2001 From: John Resig Date: Tue, 3 May 2011 21:44:42 -0400 Subject: [PATCH] If no hook is provided, and a boolean property exists, use that to return an attribute-style value for boolean attributes. Fixes #9079. --- src/attributes.js | 23 +++++++++++++++-------- test/unit/attributes.js | 33 +++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 12 deletions(-) diff --git a/src/attributes.js b/src/attributes.js index 2da2e163..9db69abc 100644 --- a/src/attributes.js +++ b/src/attributes.js @@ -285,8 +285,7 @@ jQuery.extend({ attrFix: { // Always normalize to ensure hook usage - tabindex: "tabIndex", - readonly: "readOnly" + tabindex: "tabIndex" }, attr: function( elem, name, value, pass ) { @@ -327,20 +326,25 @@ jQuery.extend({ // Set boolean attributes to the same name if ( value === true && !rspecial.test( name ) ) { - value = name; + value = name.toLowerCase(); } elem.setAttribute( name, "" + value ); return value; } - } else { + } else if ( hooks && "get" in hooks && notxml ) { + return hooks.get( elem, name ); - if ( hooks && "get" in hooks && notxml ) { - return hooks.get( elem, name ); + } else { + var boolProp = elem[ jQuery.propFix[ name ] || name ]; + + if ( typeof boolProp === "boolean" ) { + return boolProp ? + name.toLowerCase() : + undefined; } else { - ret = elem.getAttribute( name ); // Non-existent attributes return null, we normalize to undefined @@ -399,7 +403,9 @@ jQuery.extend({ } }, - propFix: {}, + propFix: { + readonly: "readOnly" + }, prop: function( elem, name, value ) { var nType = elem.nodeType; @@ -441,6 +447,7 @@ jQuery.extend({ // IE6/7 do not support getting/setting some attributes with get/setAttribute if ( !jQuery.support.getSetAttribute ) { jQuery.attrFix = jQuery.extend( jQuery.attrFix, { + readonly: "readOnly", "for": "htmlFor", "class": "className", maxlength: "maxLength", diff --git a/test/unit/attributes.js b/test/unit/attributes.js index b1cfe3db..f93cb2a6 100644 --- a/test/unit/attributes.js +++ b/test/unit/attributes.js @@ -28,8 +28,7 @@ test("jQuery.attrFix integrity test", function() { }; } else { propsShouldBe = { - tabindex: "tabIndex", - readonly: "readOnly" + tabindex: "tabIndex" }; } @@ -181,7 +180,7 @@ test("attr(Hash)", function() { }); test("attr(String, Object)", function() { - expect(35); + expect(55); var div = jQuery("div").attr("foo", "bar"), fail = false; @@ -204,12 +203,38 @@ test("attr(String, Object)", function() { equals( jQuery("#name").attr("name"), undefined, "Remove name attribute" ); jQuery("#check2").attr("checked", true); equals( document.getElementById("check2").checked, true, "Set checked attribute" ); + equals( jQuery("#check2").prop("checked"), true, "Set checked attribute" ); + equals( jQuery("#check2").attr("checked"), "checked", "Set checked attribute" ); jQuery("#check2").attr("checked", false); equals( document.getElementById("check2").checked, false, "Set checked attribute" ); + equals( jQuery("#check2").prop("checked"), false, "Set checked attribute" ); + equals( jQuery("#check2").attr("checked"), undefined, "Set checked attribute" ); jQuery("#text1").attr("readonly", true); equals( document.getElementById("text1").readOnly, true, "Set readonly attribute" ); + equals( jQuery("#text1").prop("readOnly"), true, "Set readonly attribute" ); + equals( jQuery("#text1").attr("readonly"), "readonly", "Set readonly attribute" ); jQuery("#text1").attr("readonly", false); equals( document.getElementById("text1").readOnly, false, "Set readonly attribute" ); + equals( jQuery("#text1").prop("readOnly"), false, "Set readonly attribute" ); + equals( jQuery("#text1").attr("readonly"), undefined, "Set readonly attribute" ); + + jQuery("#check2").prop("checked", true); + equals( document.getElementById("check2").checked, true, "Set checked attribute" ); + equals( jQuery("#check2").prop("checked"), true, "Set checked attribute" ); + equals( jQuery("#check2").attr("checked"), "checked", "Set checked attribute" ); + jQuery("#check2").prop("checked", false); + equals( document.getElementById("check2").checked, false, "Set checked attribute" ); + equals( jQuery("#check2").prop("checked"), false, "Set checked attribute" ); + equals( jQuery("#check2").attr("checked"), undefined, "Set checked attribute" ); + jQuery("#text1").prop("readOnly", true); + equals( document.getElementById("text1").readOnly, true, "Set readonly attribute" ); + equals( jQuery("#text1").prop("readOnly"), true, "Set readonly attribute" ); + equals( jQuery("#text1").attr("readonly"), "readonly", "Set readonly attribute" ); + jQuery("#text1").prop("readOnly", false); + equals( document.getElementById("text1").readOnly, false, "Set readonly attribute" ); + equals( jQuery("#text1").prop("readOnly"), false, "Set readonly attribute" ); + equals( jQuery("#text1").attr("readonly"), undefined, "Set readonly attribute" ); + jQuery("#name").attr("maxlength", "5"); equals( document.getElementById("name").maxLength, 5, "Set maxlength attribute" ); jQuery("#name").attr("maxLength", "10"); @@ -919,4 +944,4 @@ test("addClass, removeClass, hasClass", function() { ok( jq.hasClass("cla.ss3")==false, "Check the dotted class has been removed" ); jq.removeClass("class4"); ok( jq.hasClass("class4")==false, "Check the class has been properly removed" ); -}); \ No newline at end of file +});