Bug 1165851 part 1. Back out bug 1060938 and bug 1075702 pending spec changes because they are implementing a spec that's not web compatible. r=smaug
authorBoris Zbarsky <bzbarsky@mit.edu>
Tue, 16 Jun 2015 12:17:57 -0400
changeset 267241 03682dcd82bbb2fa45b8592d863343b2cd19f596
parent 267240 67be1324fc240c1a16f2da9743d77f689913dce5
child 267242 9d31854cecef301596a31b3ee34840719c23f9ea
push id4932
push userjlund@mozilla.com
push dateMon, 10 Aug 2015 18:23:06 +0000
treeherdermozilla-esr52@6dd5a4f5f745 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerssmaug
bugs1165851, 1060938, 1075702
milestone41.0a1
Bug 1165851 part 1. Back out bug 1060938 and bug 1075702 pending spec changes because they are implementing a spec that's not web compatible. r=smaug
dom/base/Attr.cpp
dom/base/Element.cpp
dom/base/nsDOMAttributeMap.cpp
dom/base/nsDOMAttributeMap.h
dom/base/test/mochitest.ini
dom/base/test/test_bug1060938.html
dom/base/test/test_bug1075702.html
dom/base/test/test_bug469304.html
--- a/dom/base/Attr.cpp
+++ b/dom/base/Attr.cpp
@@ -179,17 +179,17 @@ Attr::GetNameAtom(nsIContent* aContent)
   return nameAtom.forget();
 }
 
 NS_IMETHODIMP
 Attr::GetValue(nsAString& aValue)
 {
   Element* element = GetElement();
   if (element) {
-    nsCOMPtr<nsIAtom> nameAtom = mNodeInfo->NameAtom();
+    nsCOMPtr<nsIAtom> nameAtom = GetNameAtom(element);
     element->GetAttr(mNodeInfo->NamespaceID(), nameAtom, aValue);
   }
   else {
     aValue = mValue;
   }
 
   return NS_OK;
 }
@@ -198,17 +198,17 @@ void
 Attr::SetValue(const nsAString& aValue, ErrorResult& aRv)
 {
   Element* element = GetElement();
   if (!element) {
     mValue = aValue;
     return;
   }
 
-  nsCOMPtr<nsIAtom> nameAtom = mNodeInfo->NameAtom();
+  nsCOMPtr<nsIAtom> nameAtom = GetNameAtom(element);
   aRv = element->SetAttr(mNodeInfo->NamespaceID(),
                          nameAtom,
                          mNodeInfo->GetPrefixAtom(),
                          aValue,
                          true);
 }
 
 NS_IMETHODIMP
--- a/dom/base/Element.cpp
+++ b/dom/base/Element.cpp
@@ -1230,19 +1230,17 @@ Element::RemoveAttributeNode(Attr& aAttr
 {
   Element *elem = aAttribute.GetElement();
   if (elem != this) {
     aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
     return nullptr;
   }
 
   OwnerDoc()->WarnOnceAbout(nsIDocument::eRemoveAttributeNode);
-  nsAutoString nameSpaceURI;
-  aAttribute.NodeInfo()->GetNamespaceURI(nameSpaceURI);
-  return Attributes()->RemoveNamedItemNS(nameSpaceURI, aAttribute.NodeInfo()->LocalName(), aError);
+  return Attributes()->RemoveNamedItem(aAttribute.NodeName(), aError);
 }
 
 void
 Element::GetAttributeNS(const nsAString& aNamespaceURI,
                         const nsAString& aLocalName,
                         nsAString& aReturn)
 {
   int32_t nsid =
--- a/dom/base/nsDOMAttributeMap.cpp
+++ b/dom/base/nsDOMAttributeMap.cpp
@@ -295,86 +295,72 @@ nsDOMAttributeMap::SetNamedItemInternal(
     if (aError.Failed()) {
       return nullptr;
     }
 
     NS_ASSERTION(adoptedNode == &aAttr, "Uh, adopt node changed nodes?");
   }
 
   // Get nodeinfo and preexisting attribute (if it exists)
-  nsRefPtr<NodeInfo> oldNi;
-
-  if (!aWithNS) {
-    nsAutoString name;
-    aAttr.GetName(name);
-    oldNi = mContent->GetExistingAttrNameFromQName(name);
-  }
-  else {
-    uint32_t i, count = mContent->GetAttrCount();
-    for (i = 0; i < count; ++i) {
-      const nsAttrName* name = mContent->GetAttrNameAt(i);
-      int32_t attrNS = name->NamespaceID();
-      nsIAtom* nameAtom = name->LocalName();
-
-      // we're purposefully ignoring the prefix.
-      if (aAttr.NodeInfo()->Equals(nameAtom, attrNS)) {
-        oldNi = mContent->NodeInfo()->NodeInfoManager()->
-          GetNodeInfo(nameAtom, name->GetPrefix(), aAttr.NodeInfo()->NamespaceID(),
-                      nsIDOMNode::ATTRIBUTE_NODE);
-        break;
-      }
-    }
-  }
+  nsAutoString name;
+  nsRefPtr<mozilla::dom::NodeInfo> ni;
 
   nsRefPtr<Attr> attr;
+  // SetNamedItemNS()
+  if (aWithNS) {
+    // Return existing attribute, if present
+    ni = aAttr.NodeInfo();
 
-  if (oldNi) {
-    nsRefPtr<Attr> oldAttr = GetAttribute(oldNi, true);
+    if (mContent->HasAttr(ni->NamespaceID(), ni->NameAtom())) {
+      attr = RemoveAttribute(ni);
+    }
+  } else { // SetNamedItem()
+    aAttr.GetName(name);
 
-    if (oldAttr == &aAttr) {
-      return oldAttr.forget();
+    // get node-info of old attribute
+    ni = mContent->GetExistingAttrNameFromQName(name);
+    if (ni) {
+      attr = RemoveAttribute(ni);
     }
+    else {
+      if (mContent->IsInHTMLDocument() &&
+          mContent->IsHTMLElement()) {
+        nsContentUtils::ASCIIToLower(name);
+      }
 
-    if (oldAttr) {
-      attr = RemoveNamedItem(oldNi, aError);
-      NS_ASSERTION(attr->NodeInfo()->NameAndNamespaceEquals(oldNi),
-        "RemoveNamedItem() called, attr->NodeInfo() should be equal to oldNi!");
+      rv = mContent->NodeInfo()->NodeInfoManager()->
+        GetNodeInfo(name, nullptr, kNameSpaceID_None,
+                    nsIDOMNode::ATTRIBUTE_NODE, getter_AddRefs(ni));
+      if (NS_FAILED(rv)) {
+        aError.Throw(rv);
+        return nullptr;
+      }
+      // value is already empty
     }
   }
 
   nsAutoString value;
   aAttr.GetValue(value);
 
-  nsRefPtr<NodeInfo> ni = aAttr.NodeInfo();
-
   // Add the new attribute to the attribute map before updating
   // its value in the element. @see bug 364413.
   nsAttrKey attrkey(ni->NamespaceID(), ni->NameAtom());
   mAttributeCache.Put(attrkey, &aAttr);
   aAttr.SetMap(this);
 
   rv = mContent->SetAttr(ni->NamespaceID(), ni->NameAtom(),
                          ni->GetPrefixAtom(), value, true);
   if (NS_FAILED(rv)) {
     aError.Throw(rv);
     DropAttribute(ni->NamespaceID(), ni->NameAtom());
   }
 
   return attr.forget();
 }
 
-already_AddRefed<Attr>
-nsDOMAttributeMap::RemoveNamedItem(NodeInfo* aNodeInfo, ErrorResult& aError)
-{
-  nsRefPtr<Attr> attribute = GetAttribute(aNodeInfo, true);
-  // This removes the attribute node from the attribute map.
-  aError = mContent->UnsetAttr(aNodeInfo->NamespaceID(), aNodeInfo->NameAtom(), true);
-  return attribute.forget();
-}
-
 NS_IMETHODIMP
 nsDOMAttributeMap::RemoveNamedItem(const nsAString& aName,
                                    nsIDOMAttr** aReturn)
 {
   NS_ENSURE_ARG_POINTER(aReturn);
 
   ErrorResult rv;
   *aReturn = RemoveNamedItem(aName, rv).take();
@@ -390,17 +376,21 @@ nsDOMAttributeMap::RemoveNamedItem(const
   }
 
   nsRefPtr<mozilla::dom::NodeInfo> ni = mContent->GetExistingAttrNameFromQName(aName);
   if (!ni) {
     aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
     return nullptr;
   }
 
-  return RemoveNamedItem(ni, aError);
+  nsRefPtr<Attr> attribute = GetAttribute(ni, true);
+
+  // This removes the attribute node from the attribute map.
+  aError = mContent->UnsetAttr(ni->NamespaceID(), ni->NameAtom(), true);
+  return attribute.forget();
 }
 
 
 Attr*
 nsDOMAttributeMap::IndexedGetter(uint32_t aIndex, bool& aFound)
 {
   aFound = false;
   NS_ENSURE_TRUE(mContent, nullptr);
@@ -488,17 +478,16 @@ nsDOMAttributeMap::GetAttrNodeInfo(const
   }
 
   uint32_t i, count = mContent->GetAttrCount();
   for (i = 0; i < count; ++i) {
     const nsAttrName* name = mContent->GetAttrNameAt(i);
     int32_t attrNS = name->NamespaceID();
     nsIAtom* nameAtom = name->LocalName();
 
-    // we're purposefully ignoring the prefix.
     if (nameSpaceID == attrNS &&
         nameAtom->Equals(aLocalName)) {
       nsRefPtr<mozilla::dom::NodeInfo> ni;
       ni = mContent->NodeInfo()->NodeInfoManager()->
         GetNodeInfo(nameAtom, name->GetPrefix(), nameSpaceID,
                     nsIDOMNode::ATTRIBUTE_NODE);
 
       return ni.forget();
@@ -525,17 +514,21 @@ nsDOMAttributeMap::RemoveNamedItemNS(con
                                      ErrorResult& aError)
 {
   nsRefPtr<mozilla::dom::NodeInfo> ni = GetAttrNodeInfo(aNamespaceURI, aLocalName);
   if (!ni) {
     aError.Throw(NS_ERROR_DOM_NOT_FOUND_ERR);
     return nullptr;
   }
 
-  return RemoveNamedItem(ni, aError);
+  nsRefPtr<Attr> attr = RemoveAttribute(ni);
+  mozilla::dom::NodeInfo* attrNi = attr->NodeInfo();
+  mContent->UnsetAttr(attrNi->NamespaceID(), attrNi->NameAtom(), true);
+
+  return attr.forget();
 }
 
 uint32_t
 nsDOMAttributeMap::Count() const
 {
   return mAttributeCache.Count();
 }
 
--- a/dom/base/nsDOMAttributeMap.h
+++ b/dom/base/nsDOMAttributeMap.h
@@ -147,18 +147,16 @@ public:
   Attr* NamedGetter(const nsAString& aAttrName, bool& aFound);
   bool NameIsEnumerable(const nsAString& aName);
   already_AddRefed<Attr>
   SetNamedItem(Attr& aAttr, ErrorResult& aError)
   {
     return SetNamedItemInternal(aAttr, false, aError);
   }
   already_AddRefed<Attr>
-  RemoveNamedItem(mozilla::dom::NodeInfo* aNodeInfo, ErrorResult& aError);
-  already_AddRefed<Attr>
   RemoveNamedItem(const nsAString& aName, ErrorResult& aError);
  
   Attr* Item(uint32_t aIndex);
   Attr* IndexedGetter(uint32_t aIndex, bool& aFound);
   uint32_t Length() const;
 
   Attr*
   GetNamedItemNS(const nsAString& aNamespaceURI,
--- a/dom/base/test/mochitest.ini
+++ b/dom/base/test/mochitest.ini
@@ -255,17 +255,16 @@ skip-if = buildapp == 'mulet'
 [test_bug913761.html]
 [test_bug976673.html]
 [test_bug978522.html]
 [test_bug979109.html]
 [test_bug989665.html]
 [test_bug999456.html]
 [test_bug1022229.html]
 [test_bug1043106.html]
-[test_bug1060938.html]
 [test_bug1064481.html]
 [test_clearTimeoutIntervalNoArg.html]
 [test_consoleEmptyStack.html]
 [test_constructor-assignment.html]
 [test_constructor.html]
 [test_dialogArguments.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android' || e10s
 [test_document.all_unqualified.html]
@@ -661,17 +660,16 @@ skip-if = buildapp == 'mulet' || buildap
 [test_bug895974.html]
 [test_bug902847.html]
 [test_bug907892.html]
 [test_bug922681.html]
 [test_bug927196.html]
 [test_bug982153.html]
 [test_bug1057176.html]
 [test_bug1070015.html]
-[test_bug1075702.html]
 [test_bug1101364.html]
 skip-if = buildapp == 'mulet' || buildapp == 'b2g' || toolkit == 'android'
 [test_bug1163743.html]
 support-files = referrerHelper.js
 [test_bug1165501.html]
 support-files = referrerHelper.js
 [test_caretPositionFromPoint.html]
 [test_classList.html]
deleted file mode 100644
--- a/dom/base/test/test_bug1060938.html
+++ /dev/null
@@ -1,44 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=1060938
--->
-  <head>
-    <meta charset="utf-8">
-    <title> Test for Bug 1060938 </title>
-    <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"> </script>
-    <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"> </script>
-    <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-  </head>
-  <body>
-  <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1060938"> Mozilla Bug 1060938 </a>
-  <p id="display"></p>
-
-  <pre id="test">
-  <script type="application/javascript">
-
-    /** Test for Bug 1060938 **/
-    // test: Element.removeAttributeNode()
-
-    parent = document.getElementsByTagName("p")[0];
-    parent.setAttributeNS("www.test1.com", "ID", "Test1");
-    parent.setAttributeNS("www.test2.com", "Class", "Test2");
-    parent.setAttribute("id", "www.test3.com");
-    parent.className = "www.test4.com";
-
-    allAttributes = parent.attributes;
-
-    function removeAttr(iter){
-      var removed_attribute = allAttributes[0];
-      is(removed_attribute, parent.removeAttributeNode(removed_attribute),
-          "(" + iter + ")" + " Returned attribute and remove attribute should be same.");
-    }
-
-    removeAttr(1);
-    removeAttr(2);
-    removeAttr(3);
-    removeAttr(4);
-
-  </script>
-  </body>
-</html>
deleted file mode 100644
--- a/dom/base/test/test_bug1075702.html
+++ /dev/null
@@ -1,69 +0,0 @@
-<!DOCTYPE HTML>
-<html>
-<!--
-https://bugzilla.mozilla.org/show_bug.cgi?id=1075702
--->
-<head>
-  <meta charset="utf-8">
-  <title> Test for Bug 1075702 </title>
-  <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"> </script>
-  <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"> </script>
-  <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
-</head>
-<body>
-<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1075702"> Mozilla Bug 1075702 </a>
-<p id="display"></p>
-
-<pre id="test">
-<script type="application/javascript">
-
-  /** Test for Bug 1075702 **/
-  // test: Element.removeAttributeNode()
-
-  var a1 = document.createAttribute("aa");
-  a1.nodeValue = "lowercase";
-
-  var a2 = document.createAttribute("AA");
-  a2.nodeValue = "UPPERCASE";
-
-  document.documentElement.setAttributeNode(a1);
-  document.documentElement.setAttributeNode(a2);
-
-  is(document.documentElement.getAttributeNS("", "aa"), null, "Should be NULL!");
-  is(document.documentElement.getAttributeNS("", "AA"), "UPPERCASE", "Should be UPPERCASE!");
-
-  var removedNodeAccordingToEvent;
-
-  function mutationHandler(aEvent) {
-    removedNodeAccordingToEvent = aEvent.relatedNode;
-  }
-
-  var test1 = document.createElement("div");
-  test1.setAttribute("x", "y");
-  removedNodeAccordingToEvent = null;
-
-  function testremoveNamedItemNS() {
-    test1.addEventListener("DOMAttrModified", mutationHandler, true);
-    var removedNodeAccordingToRemoveNamedItemNS = test1.attributes.removeNamedItemNS(null, "x");
-    test1.removeEventListener("DOMAttrModified", mutationHandler, true);
-    is(removedNodeAccordingToEvent, removedNodeAccordingToRemoveNamedItemNS, "Node removed according to event is not same as node removed by removeNamedItemNS.");
-  }
-
-  testremoveNamedItemNS();
-
-  var test2 = document.createElement("div");
-  test2.setAttribute("x", "y");
-  removedNodeAccordingToEvent = null;
-
-  function testremoveNamedItem() {
-    test2.addEventListener("DOMAttrModified", mutationHandler, true);
-    var removedNodeAccordingToRemoveNamedItem = test2.attributes.removeNamedItem("x");
-    test2.removeEventListener("DOMAttrModified", mutationHandler, true);
-    is(removedNodeAccordingToEvent, removedNodeAccordingToRemoveNamedItem, "Node removed according to event is not same as node removed by removeNamedItem.");
-  }
-
-  testremoveNamedItem();
-
-</script>
-</body>
-</html>
--- a/dom/base/test/test_bug469304.html
+++ b/dom/base/test/test_bug469304.html
@@ -22,47 +22,47 @@ https://bugzilla.mozilla.org/show_bug.cg
 function testGetAttribute() {
   var a1 = document.createAttribute("aa");
   a1.nodeValue = "lowercase";
   var a2 = document.createAttribute("AA");
   a2.nodeValue = "UPPERCASE";
   document.body.setAttributeNode(a1);
   document.body.setAttributeNode(a2);
   var log = document.getElementById("log");
-  is(document.body.getAttribute('aa'), null, "Attribute has the localName AA and not aa.");
-  is(document.body.getAttribute('AA'), null, "Attribute has the localName AA and not aa.");
-  is(document.body.getAttributeNS("", "aa"), null, "Attribute should have localName AA.");
-  is(document.body.getAttributeNS("", "AA"), "UPPERCASE", "Attribute should have value UPPERCASE!");
+  is(document.body.getAttribute('aa'), "UPPERCASE", "Wrong value (1)");
+  is(document.body.getAttribute('AA'), "UPPERCASE", "Wrong value (2)");
 
   var s = "";
   for (var i = 0; i < document.body.attributes.length; ++i) {
     s += document.body.attributes[i].nodeName + "=" +
          document.body.attributes[i].nodeValue;
   }
   is(s, "AA=UPPERCASE", "Wrong attribute!");
 
   is(document.body.getAttributeNode("aa"), document.body.getAttributeNode("AA"),
      "Wrong node!");
 
-  document.body.getAttributeNodeNS("", "AA").nodeValue = "FOO";
-  is(document.body.getAttributeNS("", "AA"), "FOO", "Wrong value!");
+  document.body.getAttributeNode("AA").nodeValue = "FOO";
+  is(document.body.getAttribute("AA"), "FOO", "Wrong value!");
 
-  document.body.removeAttributeNode(document.body.getAttributeNodeNS("", "AA"));
+  document.body.removeAttributeNode(document.body.getAttributeNode("AA"));
+  ok(!document.body.hasAttribute("AA"), "Should not have attribute!");
   ok(!document.body.getAttributeNode("AA"), "Should not have attribute node!");
+  ok(!document.body.hasAttribute("aa"), "Should not have attribute!");
   ok(!document.body.getAttributeNode("aa"), "Should not have attribute node!");
 
   is(a2.nodeValue, "FOO", "Wrong value!");
   a2.nodeValue = "UPPERCASE";
   is(a2.nodeValue, "UPPERCASE", "Wrong value!");
 
   document.body.setAttributeNode(a2);
-  is(document.body.getAttributeNS("", "AA"), "UPPERCASE", "Wrong value!");
-  ok(document.body.getAttributeNodeNS("", "AA"), "Should have attribute node!");
-  is(document.body.getAttributeNS("", "aa"), null, "No attribute has the localName aa.");
-  ok(!document.body.getAttributeNodeNS("", "aa"), "Should not have attribute node!");
+  is(document.body.getAttribute("AA"), "UPPERCASE", "wrong value!");
+  ok(document.body.getAttributeNode("AA"), "Should have attribute node!");
+  is(document.body.getAttribute("aa"), "UPPERCASE", "wrong value!");
+  ok(document.body.getAttributeNode("aa"), "Should have attribute node!");
 }
 testGetAttribute();
 
 // A bit modified testcases from WebKit.
 function testGetAttributeCaseInsensitive() {
   var div = document.createElement('div');
   div.setAttribute("mixedCaseAttrib", "x");
   // Do original case lookup, and lowercase lookup.
@@ -70,17 +70,17 @@ function testGetAttributeCaseInsensitive
 }
 is(testGetAttributeCaseInsensitive(), "x", "(1)");
 
 function testGetAttributeNodeMixedCase() {
   var div = document.createElement('div');
   var a = div.ownerDocument.createAttribute("mixedCaseAttrib");
   a.nodeValue = "x";
   div.setAttributeNode(a);
-  return div.getAttributeNS("", "mixedCaseAttrib");
+  return div.getAttribute("mixedCaseAttrib");
 }
 is(testGetAttributeNodeMixedCase(), "x", "(2)");
 
 function testGetAttributeNodeLowerCase(div) {
   var div = document.createElement('div');
   var a = div.ownerDocument.createAttribute("lowercaseattrib");
   a.nodeValue = "x";
   div.setAttributeNode(a);
@@ -109,37 +109,37 @@ function testAttribNodeNamePreservesCase
 }
 is(testAttribNodeNamePreservesCase(), "A,A", "(5)");
 
 function testAttribNodeNamePreservesCaseGetNode() {
   var body = document.body;
   var a = body.ownerDocument.createAttribute("A");
   a.nodeValue = "x";
   body.setAttributeNode(a);
-  a = document.body.getAttributeNodeNS("", "A");
+  a = document.body.getAttributeNode("A");
   if (!a)
       return "FAIL";
   var result = [ a.name, a.nodeName ];
   return result.join(",");
 }
 is(testAttribNodeNamePreservesCaseGetNode(), "A,A", "(6)");
 
 function testAttribNodeNamePreservesCaseGetNode2() {
   var body = document.body;
   var a = body.ownerDocument.createAttribute("B");
   a.nodeValue = "x";
   body.setAttributeNode(a);
-  a = document.body.getAttributeNodeNS("", "B");
+  a = document.body.getAttributeNode("B");
   if (!a)
       return "FAIL";
   // Now create node second time
   a = body.ownerDocument.createAttribute("B");
   a.nodeValue = "x";
   body.setAttributeNode(a);
-  a = document.body.getAttributeNodeNS("", "B");
+  a = document.body.getAttributeNode("B");
   var result = [ a.name, a.nodeName ];
   return result.join(",");
 }
 is(testAttribNodeNamePreservesCaseGetNode2(), "B,B", "(7)");
 
 function testAttribNodeNameGetMutate() {
   var body = document.body;
   var a = body.ownerDocument.createAttribute("c");
@@ -153,19 +153,19 @@ function testAttribNodeNameGetMutate() {
 is(testAttribNodeNameGetMutate(), "1", "(8)");
 
 var node = document.createElement("div");
 var attrib = document.createAttribute("myAttrib");
 attrib.nodeValue = "XXX";
 node.setAttributeNode(attrib);
 // Note, this is different to what WebKit does
 is((new XMLSerializer).serializeToString(node),
-   "<div xmlns=\"http://www.w3.org/1999/xhtml\" myAttrib=\"XXX\"></div>", "(9)");
-is(node.getAttributeNodeNS("", "myAttrib").name, "myAttrib", "(10)");
-is(node.getAttributeNodeNS("", "myattrib"), null, "(11)");
+   "<div xmlns=\"http://www.w3.org/1999/xhtml\" myattrib=\"XXX\"></div>", "(9)");
+is(node.getAttributeNode('myAttrib').name, "myAttrib", "(10)");
+is(node.getAttributeNode('myattrib').name, "myAttrib", "(11)");
 is(attrib.name, "myAttrib", "(12)");
 
 var o = document.createElement("div");
 o.setAttribute("myAttrib","htmlattr");
 o.setAttributeNS("","myAttrib","123");
 is(o.getAttributeNodeNS("","myAttrib").nodeName, "myAttrib", "nodeName should be case-sensitive.");
 is(o.getAttributeNode("myAttrib").nodeName, "myattrib", "nodeName shouldn't be case-sensitive.");
 is(o.getAttributeNodeNS("","myAttrib").value, "123", "Should have got the case-sensitive attribute.");