Implement getAttributeNode() in terms of ElementAttributeData instead of NamedNodeMap
authorcaio.oliveira@openbossa.org <caio.oliveira@openbossa.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Mar 2012 23:57:40 +0000 (23:57 +0000)
committercaio.oliveira@openbossa.org <caio.oliveira@openbossa.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Wed, 7 Mar 2012 23:57:40 +0000 (23:57 +0000)
https://bugs.webkit.org/show_bug.cgi?id=80541

Reviewed by Ryosuke Niwa.

DOM methods exposed in Element and NamedNodeMap are now implemented in terms of
ElementAttributeData. The difference between them is that Element methods can early
return if there's no attribute storage.

* dom/Element.cpp:
(WebCore::Element::getAttributeNode):
Removed the manual lowercasing letting our existing mechanism in
ElementAttributeData::getAttributeItemIndex() take care of it. I considered that
this could be an optimization, but testing a few Dromaeo tests (dom-attr,
jslib-attr-jquery, jslib-attr-prototype) the difference isn't significant. It
shouldn't affect correctness either.

(WebCore::Element::getAttributeNodeNS):
* dom/ElementAttributeData.cpp:
* dom/ElementAttributeData.h:
(ElementAttributeData):
(WebCore::ElementAttributeData::getAttributeNode):
(WebCore):
* dom/NamedNodeMap.cpp:
(WebCore::NamedNodeMap::getNamedItem):
(WebCore::NamedNodeMap::getNamedItemNS):
* dom/NamedNodeMap.h:
(NamedNodeMap):

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@110119 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/dom/Element.cpp
Source/WebCore/dom/ElementAttributeData.cpp
Source/WebCore/dom/ElementAttributeData.h
Source/WebCore/dom/NamedNodeMap.cpp
Source/WebCore/dom/NamedNodeMap.h

index 97f1eaf..8fa2037 100644 (file)
@@ -1,3 +1,34 @@
+2012-03-07  Caio Marcelo de Oliveira Filho  <caio.oliveira@openbossa.org>
+
+        Implement getAttributeNode() in terms of ElementAttributeData instead of NamedNodeMap
+        https://bugs.webkit.org/show_bug.cgi?id=80541
+
+        Reviewed by Ryosuke Niwa.
+
+        DOM methods exposed in Element and NamedNodeMap are now implemented in terms of
+        ElementAttributeData. The difference between them is that Element methods can early
+        return if there's no attribute storage.
+
+        * dom/Element.cpp:
+        (WebCore::Element::getAttributeNode):
+        Removed the manual lowercasing letting our existing mechanism in
+        ElementAttributeData::getAttributeItemIndex() take care of it. I considered that
+        this could be an optimization, but testing a few Dromaeo tests (dom-attr,
+        jslib-attr-jquery, jslib-attr-prototype) the difference isn't significant. It
+        shouldn't affect correctness either.
+
+        (WebCore::Element::getAttributeNodeNS):
+        * dom/ElementAttributeData.cpp:
+        * dom/ElementAttributeData.h:
+        (ElementAttributeData):
+        (WebCore::ElementAttributeData::getAttributeNode):
+        (WebCore):
+        * dom/NamedNodeMap.cpp:
+        (WebCore::NamedNodeMap::getNamedItem):
+        (WebCore::NamedNodeMap::getNamedItemNS):
+        * dom/NamedNodeMap.h:
+        (NamedNodeMap):
+
 2012-03-07  James Robinson  <jamesr@chromium.org>
 
         [chromium] Support printing WebGL content in threaded compositor
index 44e4485..615c1c5 100644 (file)
@@ -1469,19 +1469,18 @@ void Element::removeAttributeNS(const String& namespaceURI, const String& localN
 
 PassRefPtr<Attr> Element::getAttributeNode(const String& name)
 {
-    NamedNodeMap* attrs = updatedAttributes();
-    if (!attrs)
+    ElementAttributeData* attributeData = updatedAttributeData();
+    if (!attributeData)
         return 0;
-    String localName = shouldIgnoreAttributeCase(this) ? name.lower() : name;
-    return static_pointer_cast<Attr>(attrs->getNamedItem(localName));
+    return attributeData->getAttributeNode(name, shouldIgnoreAttributeCase(this), this);
 }
 
 PassRefPtr<Attr> Element::getAttributeNodeNS(const String& namespaceURI, const String& localName)
 {
-    NamedNodeMap* attrs = updatedAttributes();
-    if (!attrs)
+    ElementAttributeData* attributeData = updatedAttributeData();
+    if (!attributeData)
         return 0;
-    return static_pointer_cast<Attr>(attrs->getNamedItem(QualifiedName(nullAtom, localName, namespaceURI)));
+    return attributeData->getAttributeNode(QualifiedName(nullAtom, localName, namespaceURI), this);
 }
 
 bool Element::hasAttribute(const String& name) const
index 093da0c..59c3ece 100644 (file)
@@ -26,7 +26,6 @@
 #include "config.h"
 #include "ElementAttributeData.h"
 
-#include "Attr.h"
 #include "StyledElement.h"
 
 namespace WebCore {
index 77fb1ec..5602ab2 100644 (file)
@@ -26,6 +26,7 @@
 #ifndef ElementAttributeData_h
 #define ElementAttributeData_h
 
+#include "Attr.h"
 #include "Attribute.h"
 #include "SpaceSplitString.h"
 #include "StylePropertySet.h"
@@ -100,6 +101,9 @@ public:
     size_t length() const { return m_attributes.size(); }
     bool isEmpty() const { return m_attributes.isEmpty(); }
 
+    PassRefPtr<Attr> getAttributeNode(const String&, bool shouldIgnoreAttributeCase, Element*) const;
+    PassRefPtr<Attr> getAttributeNode(const QualifiedName&, Element*) const;
+
     // Internal interface.
     Attribute* attributeItem(unsigned index) const { return m_attributes.attributeItem(index); }
     Attribute* getAttributeItem(const QualifiedName& name) const { return m_attributes.getAttributeItem(name); }
@@ -149,6 +153,24 @@ inline void ElementAttributeData::removeAttribute(const QualifiedName& name, Ele
     removeAttribute(index, element);
 }
 
+inline PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const String& name, bool shouldIgnoreAttributeCase, Element* element) const
+{
+    ASSERT(element);
+    Attribute* attribute = getAttributeItem(name, shouldIgnoreAttributeCase);
+    if (!attribute)
+        return 0;
+    return attribute->createAttrIfNeeded(element);
+}
+
+inline PassRefPtr<Attr> ElementAttributeData::getAttributeNode(const QualifiedName& name, Element* element) const
+{
+    ASSERT(element);
+    Attribute* attribute = getAttributeItem(name);
+    if (!attribute)
+        return 0;
+    return attribute->createAttrIfNeeded(element);
+}
+
 inline Attribute* ElementAttributeData::getAttributeItem(const String& name, bool shouldIgnoreAttributeCase) const
 {
     size_t index = getAttributeItemIndex(name, shouldIgnoreAttributeCase);
index 9c3aa78..0b7b303 100644 (file)
@@ -54,16 +54,12 @@ void NamedNodeMap::deref()
 
 PassRefPtr<Node> NamedNodeMap::getNamedItem(const String& name) const
 {
-    Attribute* a = m_attributeData.getAttributeItem(name, shouldIgnoreAttributeCase(m_element));
-    if (!a)
-        return 0;
-    
-    return a->createAttrIfNeeded(m_element);
+    return m_attributeData.getAttributeNode(name, shouldIgnoreAttributeCase(m_element), m_element);
 }
 
 PassRefPtr<Node> NamedNodeMap::getNamedItemNS(const String& namespaceURI, const String& localName) const
 {
-    return getNamedItem(QualifiedName(nullAtom, localName, namespaceURI));
+    return m_attributeData.getAttributeNode(QualifiedName(nullAtom, localName, namespaceURI), m_element);
 }
 
 PassRefPtr<Node> NamedNodeMap::removeNamedItem(const String& name, ExceptionCode& ec)
@@ -84,15 +80,6 @@ PassRefPtr<Node> NamedNodeMap::removeNamedItemNS(const String& namespaceURI, con
     return removeNamedItem(QualifiedName(nullAtom, localName, namespaceURI), ec);
 }
 
-PassRefPtr<Node> NamedNodeMap::getNamedItem(const QualifiedName& name) const
-{
-    Attribute* a = m_attributeData.getAttributeItem(name);
-    if (!a)
-        return 0;
-
-    return a->createAttrIfNeeded(m_element);
-}
-
 PassRefPtr<Node> NamedNodeMap::setNamedItem(Node* node, ExceptionCode& ec)
 {
     if (!m_element || !node) {
index 6254045..dad3198 100644 (file)
@@ -53,7 +53,6 @@ public:
     PassRefPtr<Node> getNamedItemNS(const String& namespaceURI, const String& localName) const;
     PassRefPtr<Node> removeNamedItemNS(const String& namespaceURI, const String& localName, ExceptionCode&);
 
-    PassRefPtr<Node> getNamedItem(const QualifiedName& name) const;
     PassRefPtr<Node> removeNamedItem(const QualifiedName& name, ExceptionCode&);
     PassRefPtr<Node> setNamedItem(Node*, ExceptionCode&);
     PassRefPtr<Node> setNamedItemNS(Node*, ExceptionCode&);