Title: [151470] trunk/Source/WebCore
Revision
151470
Author
[email protected]
Date
2013-06-11 14:09:33 -0700 (Tue, 11 Jun 2013)

Log Message

Split SelectorDataList::executeSingleTagNameSelectorData() into the 4 kinds of traversal
https://bugs.webkit.org/show_bug.cgi?id=117486

Patch by Benjamin Poulain <[email protected]> on 2013-06-11
Reviewed by Ryosuke Niwa.

Since this is pretty common, split the name selector to have the constant conditions
outside the traversal.

* dom/SelectorQuery.cpp:
(WebCore::SelectorDataList::executeSingleTagNameSelectorData):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (151469 => 151470)


--- trunk/Source/WebCore/ChangeLog	2013-06-11 20:55:02 UTC (rev 151469)
+++ trunk/Source/WebCore/ChangeLog	2013-06-11 21:09:33 UTC (rev 151470)
@@ -1,3 +1,16 @@
+2013-06-11  Benjamin Poulain  <[email protected]>
+
+        Split SelectorDataList::executeSingleTagNameSelectorData() into the 4 kinds of traversal
+        https://bugs.webkit.org/show_bug.cgi?id=117486
+
+        Reviewed by Ryosuke Niwa.
+
+        Since this is pretty common, split the name selector to have the constant conditions
+        outside the traversal.
+
+        * dom/SelectorQuery.cpp:
+        (WebCore::SelectorDataList::executeSingleTagNameSelectorData):
+
 2013-06-11  Eric Carlson  <[email protected]>
 
         [Mac] Update text track menu

Modified: trunk/Source/WebCore/dom/SelectorQuery.cpp (151469 => 151470)


--- trunk/Source/WebCore/dom/SelectorQuery.cpp	2013-06-11 20:55:02 UTC (rev 151469)
+++ trunk/Source/WebCore/dom/SelectorQuery.cpp	2013-06-11 21:09:33 UTC (rev 151470)
@@ -155,19 +155,62 @@
 }
 
 template <bool firstMatchOnly>
+static inline void elementsForLocalName(const Node* rootNode, const AtomicString& localName, Vector<RefPtr<Node> >& matchedElements)
+{
+    for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+        if (element->localName() == localName) {
+            matchedElements.append(element);
+            if (firstMatchOnly)
+                return;
+        }
+    }
+}
+
+template <bool firstMatchOnly>
+static inline void anyElement(const Node* rootNode, Vector<RefPtr<Node> >& matchedElements)
+{
+    for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+        matchedElements.append(element);
+        if (firstMatchOnly)
+            return;
+    }
+}
+
+
+template <bool firstMatchOnly>
 ALWAYS_INLINE void SelectorDataList::executeSingleTagNameSelectorData(const Node* rootNode, const SelectorData& selectorData, Vector<RefPtr<Node> >& matchedElements) const
 {
     ASSERT(m_selectors.size() == 1);
     ASSERT(isSingleTagNameSelector(selectorData.selector));
 
     const QualifiedName& tagQualifiedName = selectorData.selector->tagQName();
-    for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
-        if (SelectorChecker::tagMatches(element, tagQualifiedName)) {
-            matchedElements.append(element);
-            if (firstMatchOnly)
-                return;
+    const AtomicString& selectorLocalName = tagQualifiedName.localName();
+    const AtomicString& selectorNamespaceURI = tagQualifiedName.namespaceURI();
+
+    if (selectorNamespaceURI == starAtom) {
+        if (selectorLocalName != starAtom) {
+            // Common case: name defined, selectorNamespaceURI is a wildcard.
+            elementsForLocalName<firstMatchOnly>(rootNode, selectorLocalName, matchedElements);
+        } else {
+            // Other fairly common case: both are wildcards.
+            anyElement<firstMatchOnly>(rootNode, matchedElements);
         }
+    } else {
+        // Fallback: NamespaceURI is set, selectorLocalName may be starAtom.
+        for (Element* element = ElementTraversal::firstWithin(rootNode); element; element = ElementTraversal::next(element, rootNode)) {
+            if (element->namespaceURI() == selectorNamespaceURI && (selectorLocalName == starAtom || element->localName() == selectorLocalName)) {
+                matchedElements.append(element);
+                if (firstMatchOnly)
+                    break;
+            }
+        }
     }
+#if !ASSERT_DISABLED
+    for (size_t i = 0; i < matchedElements.size(); ++i) {
+        ASSERT(matchedElements[i]->isElementNode());
+        ASSERT(SelectorChecker::tagMatches(static_cast<const Element*>(matchedElements[i].get()), tagQualifiedName));
+    }
+#endif
 }
 
 static bool isSingleClassNameSelector(const CSSSelector* selector)
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to