From: Anton M <haskell_noob-github@yahoo.de>
Date: Sat, 13 Nov 2010 13:39:28 +0000 (+0100)
Subject: Make sure attr() works on non DOM element nodes. Fixes #7202, #7451, #7500.
X-Git-Url: http://git.asbjorn.it/?a=commitdiff_plain;h=b50f41a2;p=jquery.git

Make sure attr() works on non DOM element nodes. Fixes #7202, #7451, #7500.

Also added some tests for this attr(name), attr(name, value) and removeAttr(name).
---

diff --git a/src/attributes.js b/src/attributes.js
index c055fce..f463b4a 100644
--- a/src/attributes.js
+++ b/src/attributes.js
@@ -289,7 +289,7 @@ jQuery.extend({
 		name = notxml && jQuery.props[ name ] || name;
 
 		// Only do all the following if this is a node (faster for style)
-		if ( elem.nodeName ) {
+		if ( elem.nodeType === 1 ) {
 			// These attributes require special treatment
 			var special = rspecialurl.test( name );
 
@@ -373,6 +373,11 @@ jQuery.extend({
 			// 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;
+		}
+		return elem[ name ];
 	}
 });
 
diff --git a/test/unit/attributes.js b/test/unit/attributes.js
index 2d0a0d6..7314b3a 100644
--- a/test/unit/attributes.js
+++ b/test/unit/attributes.js
@@ -4,7 +4,7 @@ var bareObj = function(value) { return value; };
 var functionReturningObj = function(value) { return (function() { return value; }); };
 
 test("attr(String)", function() {
-	expect(31);
+	expect(37);
 
 	// This one sometimes fails randomly ?!
 	equals( jQuery('#text1').attr('value'), "Test", 'Check for value attribute' );
@@ -67,6 +67,14 @@ test("attr(String)", function() {
 	ok( jQuery().attr("doesntexist") === undefined, "Make sure undefined is returned when no element is there." );
 
 	equals( jQuery(document).attr("nodeName"), "#document", "attr works correctly on document nodes (bug #7451)." );
+
+	var attributeNode = document.createAttribute("irrelevant"),
+		commentNode = document.createComment("some comment"),
+		textNode = document.createTextNode("some text"),
+		obj = {};
+	jQuery.each( [document, attributeNode, commentNode, textNode, obj, "#firstp"], function( i, ele ) {
+		strictEqual( jQuery(ele).attr("nonexisting"), undefined, "attr works correctly for non existing attributes (bug #7500)." );
+	});
 });
 
 if ( !isLocal ) {
@@ -100,7 +108,7 @@ test("attr(Hash)", function() {
 });
 
 test("attr(String, Object)", function() {
-	expect(24);
+	expect(30);
 
 	var div = jQuery("div").attr("foo", "bar"),
 		fail = false;
@@ -134,6 +142,25 @@ test("attr(String, Object)", function() {
 	jQuery("#name").attr('maxLength', '10');
 	equals( document.getElementById('name').maxLength, '10', 'Set maxlength attribute' );
 
+	var attributeNode = document.createAttribute("irrelevant"),
+		commentNode = document.createComment("some comment"),
+		textNode = document.createTextNode("some text"),
+		obj = {};
+	jQuery.each( [document, attributeNode, obj, "#firstp"], function( i, ele ) {
+		var $ele = jQuery( ele );
+		$ele.attr( "nonexisting", "foo" );
+		equal( $ele.attr("nonexisting"), "foo", "attr(name, value) works correctly for non existing attributes (bug #7500)." );
+	});
+	jQuery.each( [commentNode, textNode], function( i, ele ) {
+		var $ele = jQuery( ele );
+		$ele.attr( "nonexisting", "foo" );
+		strictEqual( $ele.attr("nonexisting"), undefined, "attr(name, value) works correctly on comment and text nodes (bug #7500)." );
+	});
+	//cleanup
+	jQuery.each( [document, "#firstp"], function( i, ele ) {
+		jQuery( ele ).removeAttr("nonexisting");
+	});
+
 	var table = jQuery('#table').append("<tr><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr><tr><td>cell</td><td>cell</td></tr>"),
 		td = table.find('td:first');
 	td.attr("rowspan", "2");
@@ -304,8 +331,26 @@ test("attr('tabindex', value)", function() {
 });
 
 test("removeAttr(String)", function() {
-	expect(1);
+	expect(7);
 	equals( jQuery('#mark').removeAttr( "class" )[0].className, "", "remove class" );
+
+	var attributeNode = document.createAttribute("irrelevant"),
+		commentNode = document.createComment("some comment"),
+		textNode = document.createTextNode("some text"),
+		obj = {};
+	//removeAttr only really removes on DOM element nodes handle all other seperatyl
+	strictEqual( jQuery( "#firstp" ).attr( "nonexisting", "foo" ).removeAttr( "nonexisting" )[0].nonexisting, undefined, "removeAttr works correctly on DOM element nodes" );
+
+	jQuery.each( [document, attributeNode, obj], function( i, ele ) {
+		var $ele = jQuery( ele );
+		$ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" );
+		strictEqual( ele.nonexisting, "", "removeAttr works correctly on non DOM element nodes (bug #7500)." );
+	});
+	jQuery.each( [commentNode, textNode], function( i, ele ) {
+		$ele = jQuery( ele );
+		$ele.attr( "nonexisting", "foo" ).removeAttr( "nonexisting" );
+		strictEqual( ele.nonexisting, undefined, "removeAttr works correctly on non DOM element nodes (bug #7500)." );
+	});
 });
 
 test("val()", function() {