Title: [229368] trunk/Source/WebCore
Revision
229368
Author
an...@apple.com
Date
2018-03-07 10:27:55 -0800 (Wed, 07 Mar 2018)

Log Message

checkForSiblingStyleChanges should use internal versions of the invalidation functions
https://bugs.webkit.org/show_bug.cgi?id=183405
<rdar://problem/38218310>

Reviewed by Zalan Bujtas.

Non-internal invalidateStyleForElement/Subtree() implement sibling combinator invalidation. Checking this
is only needed if the element in question changed somehow. In checkForSiblingStyleChanges we know that
another element changed and we really just want to invalidate.

* css/SelectorChecker.cpp:
(WebCore::isFirstOfType):
(WebCore::SelectorChecker::checkOne const):

Also make :first-of-type use ChildrenAffectedByForwardPositionalRules for invalidation similar to :last-of-type
for more correct invalidation.

* dom/Element.cpp:
(WebCore::checkForSiblingStyleChanges):

Modified Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (229367 => 229368)


--- trunk/Source/WebCore/ChangeLog	2018-03-07 18:21:41 UTC (rev 229367)
+++ trunk/Source/WebCore/ChangeLog	2018-03-07 18:27:55 UTC (rev 229368)
@@ -1,3 +1,25 @@
+2018-03-07  Antti Koivisto  <an...@apple.com>
+
+        checkForSiblingStyleChanges should use internal versions of the invalidation functions
+        https://bugs.webkit.org/show_bug.cgi?id=183405
+        <rdar://problem/38218310>
+
+        Reviewed by Zalan Bujtas.
+
+        Non-internal invalidateStyleForElement/Subtree() implement sibling combinator invalidation. Checking this
+        is only needed if the element in question changed somehow. In checkForSiblingStyleChanges we know that
+        another element changed and we really just want to invalidate.
+
+        * css/SelectorChecker.cpp:
+        (WebCore::isFirstOfType):
+        (WebCore::SelectorChecker::checkOne const):
+
+        Also make :first-of-type use ChildrenAffectedByForwardPositionalRules for invalidation similar to :last-of-type
+        for more correct invalidation.
+
+        * dom/Element.cpp:
+        (WebCore::checkForSiblingStyleChanges):
+
 2018-03-07  Yusuke Suzuki  <utatane....@gmail.com>
 
         HTML `pattern` attribute should set `u` flag for regular expressions

Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (229367 => 229368)


--- trunk/Source/WebCore/css/SelectorChecker.cpp	2018-03-07 18:21:41 UTC (rev 229367)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp	2018-03-07 18:27:55 UTC (rev 229368)
@@ -103,11 +103,9 @@
     return !ElementTraversal::nextSibling(element);
 }
 
-static inline bool isFirstOfType(SelectorChecker::CheckingContext& checkingContext, const Element& element, const QualifiedName& type)
+static inline bool isFirstOfType(const Element& element, const QualifiedName& type)
 {
     for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
-        addStyleRelation(checkingContext, *sibling, Style::Relation::AffectsNextSibling);
-
         if (sibling->hasTagName(type))
             return false;
     }
@@ -745,9 +743,9 @@
             break;
         case CSSSelector::PseudoClassFirstOfType:
             // first-of-type matches the first element of its type
-            if (element.parentElement()) {
-                addStyleRelation(checkingContext, element, Style::Relation::AffectedByPreviousSibling);
-                return isFirstOfType(checkingContext, element, element.tagQName());
+            if (auto* parentElement = element.parentElement()) {
+                addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByForwardPositionalRules);
+                return isFirstOfType(element, element.tagQName());
             }
             break;
         case CSSSelector::PseudoClassLastChild:
@@ -785,11 +783,11 @@
         case CSSSelector::PseudoClassOnlyOfType:
             // FIXME: This selector is very slow.
             if (Element* parentElement = element.parentElement()) {
-                addStyleRelation(checkingContext, element, Style::Relation::AffectedByPreviousSibling);
+                addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByForwardPositionalRules);
                 addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByBackwardPositionalRules);
                 if (!parentElement->isFinishedParsingChildren())
                     return false;
-                return isFirstOfType(checkingContext, element, element.tagQName()) && isLastOfType(element, element.tagQName());
+                return isFirstOfType(element, element.tagQName()) && isLastOfType(element, element.tagQName());
             }
             break;
         case CSSSelector::PseudoClassMatches:

Modified: trunk/Source/WebCore/dom/Element.cpp (229367 => 229368)


--- trunk/Source/WebCore/dom/Element.cpp	2018-03-07 18:21:41 UTC (rev 229367)
+++ trunk/Source/WebCore/dom/Element.cpp	2018-03-07 18:27:55 UTC (rev 229368)
@@ -1480,6 +1480,16 @@
     return styleResolver().styleForElement(*this, parentStyle);
 }
 
+static void invalidateForSiblingCombinators(Element* sibling)
+{
+    for (; sibling; sibling = sibling->nextElementSibling()) {
+        if (sibling->styleIsAffectedByPreviousSibling())
+            sibling->invalidateStyleForSubtreeInternal();
+        if (!sibling->affectsNextSiblingElementStyle())
+            return;
+    }
+}
+
 static void invalidateSiblingsIfNeeded(Element& element)
 {
     if (!element.affectsNextSiblingElementStyle())
@@ -1488,12 +1498,7 @@
     if (parent && parent->styleValidity() >= Style::Validity::SubtreeInvalid)
         return;
 
-    for (auto* sibling = element.nextElementSibling(); sibling; sibling = sibling->nextElementSibling()) {
-        if (sibling->styleIsAffectedByPreviousSibling())
-            sibling->invalidateStyleForSubtreeInternal();
-        if (!sibling->affectsNextSiblingElementStyle())
-            return;
-    }
+    invalidateForSiblingCombinators(element.nextElementSibling());
 }
 
 void Element::invalidateStyle()
@@ -2027,7 +2032,7 @@
         if (newFirstElement != elementAfterChange) {
             auto* style = elementAfterChange->renderStyle();
             if (!style || style->firstChildState())
-                elementAfterChange->invalidateStyleForSubtree();
+                elementAfterChange->invalidateStyleForSubtreeInternal();
         }
 
         // We also have to handle node removal.
@@ -2034,7 +2039,7 @@
         if (checkType == SiblingElementRemoved && newFirstElement == elementAfterChange && newFirstElement) {
             auto* style = newFirstElement->renderStyle();
             if (!style || !style->firstChildState())
-                newFirstElement->invalidateStyleForSubtree();
+                newFirstElement->invalidateStyleForSubtreeInternal();
         }
     }
 
@@ -2047,7 +2052,7 @@
         if (newLastElement != elementBeforeChange) {
             auto* style = elementBeforeChange->renderStyle();
             if (!style || style->lastChildState())
-                elementBeforeChange->invalidateStyleForSubtree();
+                elementBeforeChange->invalidateStyleForSubtreeInternal();
         }
 
         // We also have to handle node removal.  The parser callback case is similar to node removal as well in that we need to change the last child
@@ -2055,34 +2060,22 @@
         if ((checkType == SiblingElementRemoved || checkType == FinishedParsingChildren) && newLastElement == elementBeforeChange && newLastElement) {
             auto* style = newLastElement->renderStyle();
             if (!style || !style->lastChildState())
-                newLastElement->invalidateStyleForSubtree();
+                newLastElement->invalidateStyleForSubtreeInternal();
         }
     }
 
-    if (elementAfterChange) {
-        if (elementAfterChange->styleIsAffectedByPreviousSibling())
-            elementAfterChange->invalidateStyleForSubtree();
-        else if (elementAfterChange->affectsNextSiblingElementStyle()) {
-            Element* elementToInvalidate = elementAfterChange;
-            do {
-                elementToInvalidate = elementToInvalidate->nextElementSibling();
-            } while (elementToInvalidate && !elementToInvalidate->styleIsAffectedByPreviousSibling());
+    invalidateForSiblingCombinators(elementAfterChange);
 
-            if (elementToInvalidate)
-                elementToInvalidate->invalidateStyleForSubtree();
-        }
-    }
-
     // We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
     // backward case.
     if (parent.childrenAffectedByForwardPositionalRules()) {
         for (auto* next = elementAfterChange; next; next = next->nextElementSibling())
-            next->invalidateStyleForSubtree();
+            next->invalidateStyleForSubtreeInternal();
     }
     // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
     if (parent.childrenAffectedByBackwardPositionalRules()) {
         for (auto* previous = elementBeforeChange; previous; previous = previous->previousElementSibling())
-            previous->invalidateStyleForSubtree();
+            previous->invalidateStyleForSubtreeInternal();
     }
 }
 
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to