Title: [103165] trunk/Source/WebCore
Revision
103165
Author
[email protected]
Date
2011-12-17 19:41:45 -0800 (Sat, 17 Dec 2011)

Log Message

HTMLCollection: Simplify itemAfter().
<http://webkit.org/b/74795>

Reviewed by Antti Koivisto.

Whether to do deep traversal of children depends on m_type which
doesn't change after construction, so move that decision there
by caching it in a "m_includeChildren" bit.

Also factored out the big switch statement in itemAfter() into
an isAcceptableElement() function.

Last and least, use fastHasAttribute() to check for itempropAttr
since it's not SVG animatable.

* html/HTMLCollection.cpp:
(WebCore::HTMLCollection::HTMLCollection):
(WebCore::HTMLCollection::shouldIncludeChildren):
(WebCore::HTMLCollection::isAcceptableElement):
(WebCore::HTMLCollection::itemAfter):
* html/HTMLCollection.h:

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (103164 => 103165)


--- trunk/Source/WebCore/ChangeLog	2011-12-18 03:35:12 UTC (rev 103164)
+++ trunk/Source/WebCore/ChangeLog	2011-12-18 03:41:45 UTC (rev 103165)
@@ -1,5 +1,29 @@
 2011-12-17  Andreas Kling  <[email protected]>
 
+        HTMLCollection: Simplify itemAfter().
+        <http://webkit.org/b/74795>
+
+        Reviewed by Antti Koivisto.
+
+        Whether to do deep traversal of children depends on m_type which
+        doesn't change after construction, so move that decision there
+        by caching it in a "m_includeChildren" bit.
+
+        Also factored out the big switch statement in itemAfter() into
+        an isAcceptableElement() function.
+
+        Last and least, use fastHasAttribute() to check for itempropAttr
+        since it's not SVG animatable.
+
+        * html/HTMLCollection.cpp:
+        (WebCore::HTMLCollection::HTMLCollection):
+        (WebCore::HTMLCollection::shouldIncludeChildren):
+        (WebCore::HTMLCollection::isAcceptableElement):
+        (WebCore::HTMLCollection::itemAfter):
+        * html/HTMLCollection.h:
+
+2011-12-17  Andreas Kling  <[email protected]>
+
         TagNodeList: Optimize nodeMatches() for the common case.
         <http://webkit.org/b/74796>
 

Modified: trunk/Source/WebCore/html/HTMLCollection.cpp (103164 => 103165)


--- trunk/Source/WebCore/html/HTMLCollection.cpp	2011-12-18 03:35:12 UTC (rev 103164)
+++ trunk/Source/WebCore/html/HTMLCollection.cpp	2011-12-18 03:41:45 UTC (rev 103165)
@@ -38,6 +38,7 @@
 
 HTMLCollection::HTMLCollection(Document* document, CollectionType type)
     : m_baseIsRetained(false)
+    , m_includeChildren(shouldIncludeChildren(type))
     , m_ownsInfo(false)
     , m_type(type)
     , m_base(document)
@@ -47,6 +48,7 @@
 
 HTMLCollection::HTMLCollection(PassRefPtr<Node> base, CollectionType type, CollectionCache* info)
     : m_baseIsRetained(true)
+    , m_includeChildren(shouldIncludeChildren(type))
     , m_ownsInfo(false)
     , m_type(type)
     , m_base(base.get())
@@ -55,6 +57,38 @@
     m_base->ref();
 }
 
+bool HTMLCollection::shouldIncludeChildren(CollectionType type)
+{
+    switch (type) {
+    case DocAll:
+    case DocAnchors:
+    case DocApplets:
+    case DocEmbeds:
+    case DocForms:
+    case DocImages:
+    case DocLinks:
+    case DocObjects:
+    case DocScripts:
+    case DocumentNamedItems:
+    case MapAreas:
+    case OtherCollection:
+    case SelectOptions:
+    case DataListOptions:
+    case WindowNamedItems:
+#if ENABLE(MICRODATA)
+    case ItemProperties:
+#endif
+        return true;
+    case NodeChildren:
+    case TRCells:
+    case TSectionRows:
+    case TableTBodies:
+        return false;
+    }
+    ASSERT_NOT_REACHED();
+    return false;
+}
+
 PassRefPtr<HTMLCollection> HTMLCollection::createForCachingOnDocument(Document* document, CollectionType type)
 {
     return adoptRef(new HTMLCollection(document, type));
@@ -90,6 +124,57 @@
     }
 }
 
+inline bool HTMLCollection::isAcceptableElement(Element* element) const
+{
+    switch (m_type) {
+    case DocImages:
+        return element->hasLocalName(imgTag);
+    case DocScripts:
+        return element->hasLocalName(scriptTag);
+    case DocForms:
+        return element->hasLocalName(formTag);
+    case TableTBodies:
+        return element->hasLocalName(tbodyTag);
+    case TRCells:
+        return element->hasLocalName(tdTag) || element->hasLocalName(thTag);
+    case TSectionRows:
+        return element->hasLocalName(trTag);
+    case SelectOptions:
+        return element->hasLocalName(optionTag);
+    case DataListOptions:
+        if (element->hasLocalName(optionTag)) {
+            HTMLOptionElement* option = static_cast<HTMLOptionElement*>(element);
+            if (!option->disabled() && !option->value().isEmpty())
+                return true;
+        }
+        return false;
+    case MapAreas:
+        return element->hasLocalName(areaTag);
+    case DocApplets:
+        return element->hasLocalName(appletTag) || (element->hasLocalName(objectTag) && static_cast<HTMLObjectElement*>(element)->containsJavaApplet());
+    case DocEmbeds:
+        return element->hasLocalName(embedTag);
+    case DocObjects:
+        return element->hasLocalName(objectTag);
+    case DocLinks:
+        return (element->hasLocalName(aTag) || element->hasLocalName(areaTag)) && element->fastHasAttribute(hrefAttr);
+    case DocAnchors:
+        return element->hasLocalName(aTag) && element->fastHasAttribute(nameAttr);
+    case DocAll:
+    case NodeChildren:
+        return true;
+#if ENABLE(MICRODATA)
+    case ItemProperties:
+        return element->isHTMLElement() && element->fastHasAttribute(itempropAttr);
+#endif
+    case DocumentNamedItems:
+    case OtherCollection:
+    case WindowNamedItems:
+        ASSERT_NOT_REACHED();
+    }
+    return false;
+}
+
 static Node* nextNodeOrSibling(Node* base, Node* node, bool includeChildren)
 {
     return includeChildren ? node->traverseNextNode(base) : node->traverseNextSibling(base);
@@ -97,123 +182,18 @@
 
 Element* HTMLCollection::itemAfter(Element* previous) const
 {
-    bool deep = true;
-
-    switch (m_type) {
-        case DocAll:
-        case DocAnchors:
-        case DocApplets:
-        case DocEmbeds:
-        case DocForms:
-        case DocImages:
-        case DocLinks:
-        case DocObjects:
-        case DocScripts:
-        case DocumentNamedItems:
-        case MapAreas:
-        case OtherCollection:
-        case SelectOptions:
-        case DataListOptions:
-        case WindowNamedItems:
-#if ENABLE(MICRODATA)
-        case ItemProperties:
-#endif
-            break;
-        case NodeChildren:
-        case TRCells:
-        case TSectionRows:
-        case TableTBodies:
-            deep = false;
-            break;
-    }
-
     Node* current;
     if (!previous)
         current = m_base->firstChild();
     else
-        current = nextNodeOrSibling(m_base, previous, deep);
+        current = nextNodeOrSibling(m_base, previous, m_includeChildren);
 
-    for (; current; current = nextNodeOrSibling(m_base, current, deep)) {
+    for (; current; current = nextNodeOrSibling(m_base, current, m_includeChildren)) {
         if (!current->isElementNode())
             continue;
-        Element* e = static_cast<Element*>(current);
-        switch (m_type) {
-            case DocImages:
-                if (e->hasLocalName(imgTag))
-                    return e;
-                break;
-            case DocScripts:
-                if (e->hasLocalName(scriptTag))
-                    return e;
-                break;
-            case DocForms:
-                if (e->hasLocalName(formTag))
-                    return e;
-                break;
-            case TableTBodies:
-                if (e->hasLocalName(tbodyTag))
-                    return e;
-                break;
-            case TRCells:
-                if (e->hasLocalName(tdTag) || e->hasLocalName(thTag))
-                    return e;
-                break;
-            case TSectionRows:
-                if (e->hasLocalName(trTag))
-                    return e;
-                break;
-            case SelectOptions:
-                if (e->hasLocalName(optionTag))
-                    return e;
-                break;
-            case DataListOptions:
-                if (e->hasLocalName(optionTag)) {
-                    HTMLOptionElement* option = static_cast<HTMLOptionElement*>(e);
-                    if (!option->disabled() && !option->value().isEmpty())
-                        return e;
-                }
-                break;
-            case MapAreas:
-                if (e->hasLocalName(areaTag))
-                    return e;
-                break;
-            case DocApplets: // all <applet> elements and <object> elements that contain Java Applets
-                if (e->hasLocalName(appletTag))
-                    return e;
-                if (e->hasLocalName(objectTag) && static_cast<HTMLObjectElement*>(e)->containsJavaApplet())
-                    return e;
-                break;
-            case DocEmbeds:
-                if (e->hasLocalName(embedTag))
-                    return e;
-                break;
-            case DocObjects:
-                if (e->hasLocalName(objectTag))
-                    return e;
-                break;
-            case DocLinks: // all <a> and <area> elements with a value for href
-                if ((e->hasLocalName(aTag) || e->hasLocalName(areaTag)) && e->fastHasAttribute(hrefAttr))
-                    return e;
-                break;
-            case DocAnchors: // all <a> elements with a value for name
-                if (e->hasLocalName(aTag) && e->fastHasAttribute(nameAttr))
-                    return e;
-                break;
-            case DocAll:
-            case NodeChildren:
-                return e;
-#if ENABLE(MICRODATA)
-            case ItemProperties:
-                if (e->isHTMLElement() && e->hasAttribute(itempropAttr))
-                    return e;
-                break;
-#endif
-            case DocumentNamedItems:
-            case OtherCollection:
-            case WindowNamedItems:
-                ASSERT_NOT_REACHED();
-                break;
-        }
+        Element* element = static_cast<Element*>(current);
+        if (isAcceptableElement(element))
+            return element;
     }
 
     return 0;

Modified: trunk/Source/WebCore/html/HTMLCollection.h (103164 => 103165)


--- trunk/Source/WebCore/html/HTMLCollection.h	2011-12-18 03:35:12 UTC (rev 103164)
+++ trunk/Source/WebCore/html/HTMLCollection.h	2011-12-18 03:41:45 UTC (rev 103165)
@@ -71,10 +71,15 @@
     bool checkForNameMatch(Element*, bool checkName, const AtomicString& name) const;
 
 private:
+    static bool shouldIncludeChildren(CollectionType);
+
     virtual unsigned calcLength() const;
     virtual void updateNameCache() const;
 
+    bool isAcceptableElement(Element*) const;
+
     bool m_baseIsRetained : 1;
+    bool m_includeChildren : 1;
     mutable bool m_ownsInfo : 1;
     unsigned m_type : 5; // CollectionType
 
_______________________________________________
webkit-changes mailing list
[email protected]
http://lists.webkit.org/mailman/listinfo.cgi/webkit-changes

Reply via email to