Title: [199368] releases/WebKitGTK/webkit-2.12
Revision
199368
Author
[email protected]
Date
2016-04-12 09:50:02 -0700 (Tue, 12 Apr 2016)

Log Message

Merge r198216 - REGRESSION (196383): Class change invalidation does not handle :not correctly
https://bugs.webkit.org/show_bug.cgi?id=155493
<rdar://problem/24846762>

Reviewed by Andreas Kling.

We fail to invalidate bar style in

    :not(.foo) bar { }

when class foo is added or removed.

There is a logic error in the invalidation code. It assumes that class addition can only make new selectors match
and removal make them not match. This is not true when :not is present.

* style/AttributeChangeInvalidation.h:
(WebCore::Style::AttributeChangeInvalidation::AttributeChangeInvalidation):
* style/ClassChangeInvalidation.cpp:
(WebCore::Style::ClassChangeInvalidation::invalidateStyle):

    Invalidate style and collect full set of rules that may affect descendant style.

(WebCore::Style::ClassChangeInvalidation::invalidateDescendantStyle):

    Invalidate with this set both before and after committing the changes.

(WebCore::Style::ClassChangeInvalidation::computeClassChange): Deleted.
* style/ClassChangeInvalidation.h:
(WebCore::Style::ClassChangeInvalidation::ClassChangeInvalidation):
(WebCore::Style::ClassChangeInvalidation::~ClassChangeInvalidation):

LayoutTests:
Class change invalidation does not handle :not correctly
https://bugs.webkit.org/show_bug.cgi?id=155493
<rdar://problem/24846762>

Reviewed by Andreas Kling.

* fast/css/style-invalidation-attribute-change-descendants-expected.txt:
* fast/css/style-invalidation-attribute-change-descendants.html:

    Also add :not case for attribute changes (which handles this correctly already).

* fast/css/style-invalidation-class-change-descendants-expected.txt:
* fast/css/style-invalidation-class-change-descendants.html:

    Add :not case.

Modified Paths

Diff

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog (199367 => 199368)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog	2016-04-12 16:46:37 UTC (rev 199367)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/ChangeLog	2016-04-12 16:50:02 UTC (rev 199368)
@@ -1,3 +1,21 @@
+2016-03-15  Antti Koivisto  <[email protected]>
+
+        Class change invalidation does not handle :not correctly
+        https://bugs.webkit.org/show_bug.cgi?id=155493
+        <rdar://problem/24846762>
+
+        Reviewed by Andreas Kling.
+
+        * fast/css/style-invalidation-attribute-change-descendants-expected.txt:
+        * fast/css/style-invalidation-attribute-change-descendants.html:
+
+            Also add :not case for attribute changes (which handles this correctly already).
+
+        * fast/css/style-invalidation-class-change-descendants-expected.txt:
+        * fast/css/style-invalidation-class-change-descendants.html:
+
+            Add :not case.
+
 2016-03-10  Antonio Gomes  <[email protected]>
 
         Selecting with shift+drag results in unexpected drag-n-drop

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-attribute-change-descendants-expected.txt (199367 => 199368)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-attribute-change-descendants-expected.txt	2016-04-12 16:46:37 UTC (rev 199367)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-attribute-change-descendants-expected.txt	2016-04-12 16:50:02 UTC (rev 199368)
@@ -3,6 +3,7 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
+Setting attribute 'mynotattr' value ''
 PASS hasExpectedStyle is true
 PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
 PASS testStyleChangeType("target", "NoStyleChange") is true
@@ -143,6 +144,16 @@
 PASS testStyleChangeType("target", "NoStyleChange") is true
 PASS testStyleChangeType("inert", "NoStyleChange") is true
 PASS hasExpectedStyle is true
+Removing attribute 'mynotattr'
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "InlineStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
+Setting attribute 'mynotattr' value 'value'
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "InlineStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-attribute-change-descendants.html (199367 => 199368)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-attribute-change-descendants.html	2016-04-12 16:46:37 UTC (rev 199367)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-attribute-change-descendants.html	2016-04-12 16:50:02 UTC (rev 199368)
@@ -42,6 +42,10 @@
     color: rgb(9, 0, 0);
 }
 
+root:not([mynotattr]) target {
+    color: rgb(10, 0, 0);
+}
+
 </style>
 </head>
 <body>
@@ -125,6 +129,8 @@
     shouldBeTrue("hasExpectedStyle");
 }
 
+setAttribute('mynotattr', '');
+
 checkStyle(0);
 testStyleInvalidation("NoStyleChange");
 checkStyle(0);
@@ -237,6 +243,14 @@
 testStyleInvalidation("NoStyleChange");
 checkStyle(1);
 
+removeAttribute('mynotattr');
+testStyleInvalidation("InlineStyleChange");
+checkStyle(10);
+
+setAttribute('mynotattr', 'value');
+testStyleInvalidation("InlineStyleChange");
+checkStyle(1);
+
 </script>
 <script src=""
 </html>

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-class-change-descendants-expected.txt (199367 => 199368)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-class-change-descendants-expected.txt	2016-04-12 16:46:37 UTC (rev 199367)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-class-change-descendants-expected.txt	2016-04-12 16:50:02 UTC (rev 199368)
@@ -3,6 +3,7 @@
 On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
 
 
+Adding class style5
 PASS hasExpectedStyle is true
 PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
 PASS testStyleChangeType("target", "NoStyleChange") is true
@@ -51,6 +52,16 @@
 PASS testStyleChangeType("target", "InlineStyleChange") is true
 PASS testStyleChangeType("inert", "NoStyleChange") is true
 PASS hasExpectedStyle is true
+Removing class style5
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "InlineStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
+Adding class style5
+PASS testStyleChangeType("root", "NoStyleChange") || testStyleChangeType("root", "InlineStyleChange") is true
+PASS testStyleChangeType("target", "InlineStyleChange") is true
+PASS testStyleChangeType("inert", "NoStyleChange") is true
+PASS hasExpectedStyle is true
 PASS successfullyParsed is true
 
 TEST COMPLETE

Modified: releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-class-change-descendants.html (199367 => 199368)


--- releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-class-change-descendants.html	2016-04-12 16:46:37 UTC (rev 199367)
+++ releases/WebKitGTK/webkit-2.12/LayoutTests/fast/css/style-invalidation-class-change-descendants.html	2016-04-12 16:50:02 UTC (rev 199368)
@@ -22,6 +22,10 @@
     color: rgb(4, 4, 4);
 }
 
+root:not(.style5) target {
+    color: rgb(5, 5, 5);
+}
+
 </style>
 </head>
 <body>
@@ -105,6 +109,8 @@
     shouldBeTrue("hasExpectedStyle");
 }
 
+addClass('style5');
+
 checkStyle(0);
 testStyleInvalidation("NoStyleChange");
 checkStyle(0);
@@ -143,6 +149,14 @@
 testStyleInvalidation("InlineStyleChange");
 checkStyle(0);
 
+removeClass('style5');
+testStyleInvalidation("InlineStyleChange");
+checkStyle(5);
+
+addClass('style5');
+testStyleInvalidation("InlineStyleChange");
+checkStyle(0);
+
 </script>
 <script src=""
 </html>

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog (199367 => 199368)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog	2016-04-12 16:46:37 UTC (rev 199367)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/ChangeLog	2016-04-12 16:50:02 UTC (rev 199368)
@@ -1,3 +1,36 @@
+2016-03-15  Antti Koivisto  <[email protected]>
+
+        REGRESSION (196383): Class change invalidation does not handle :not correctly
+        https://bugs.webkit.org/show_bug.cgi?id=155493
+        <rdar://problem/24846762>
+
+        Reviewed by Andreas Kling.
+
+        We fail to invalidate bar style in
+
+            :not(.foo) bar { }
+
+        when class foo is added or removed.
+
+        There is a logic error in the invalidation code. It assumes that class addition can only make new selectors match
+        and removal make them not match. This is not true when :not is present.
+
+        * style/AttributeChangeInvalidation.h:
+        (WebCore::Style::AttributeChangeInvalidation::AttributeChangeInvalidation):
+        * style/ClassChangeInvalidation.cpp:
+        (WebCore::Style::ClassChangeInvalidation::invalidateStyle):
+
+            Invalidate style and collect full set of rules that may affect descendant style.
+
+        (WebCore::Style::ClassChangeInvalidation::invalidateDescendantStyle):
+
+            Invalidate with this set both before and after committing the changes.
+
+        (WebCore::Style::ClassChangeInvalidation::computeClassChange): Deleted.
+        * style/ClassChangeInvalidation.h:
+        (WebCore::Style::ClassChangeInvalidation::ClassChangeInvalidation):
+        (WebCore::Style::ClassChangeInvalidation::~ClassChangeInvalidation):
+
 2016-03-15  Miguel Gomez  <[email protected]>
 
         Leak: Accelerated ImageBufferCairo doesn't destroy the used textures

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/style/AttributeChangeInvalidation.h (199367 => 199368)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/style/AttributeChangeInvalidation.h	2016-04-12 16:46:37 UTC (rev 199367)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/style/AttributeChangeInvalidation.h	2016-04-12 16:50:02 UTC (rev 199368)
@@ -46,7 +46,7 @@
     const bool m_isEnabled;
     Element& m_element;
 
-    RuleSet* m_descendantInvalidationRuleSet { nullptr };
+    const RuleSet* m_descendantInvalidationRuleSet { nullptr };
 };
 
 inline AttributeChangeInvalidation::AttributeChangeInvalidation(Element& element, const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/style/ClassChangeInvalidation.cpp (199367 => 199368)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/style/ClassChangeInvalidation.cpp	2016-04-12 16:46:37 UTC (rev 199367)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/style/ClassChangeInvalidation.cpp	2016-04-12 16:50:02 UTC (rev 199368)
@@ -34,7 +34,9 @@
 namespace WebCore {
 namespace Style {
 
-auto ClassChangeInvalidation::collectClasses(const SpaceSplitString& classes) -> ClassChangeVector
+using ClassChangeVector = Vector<AtomicStringImpl*, 4>;
+
+static ClassChangeVector collectClasses(const SpaceSplitString& classes)
 {
     ClassChangeVector result;
     result.reserveCapacity(classes.size());
@@ -43,20 +45,18 @@
     return result;
 }
 
-void ClassChangeInvalidation::computeClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses)
+static ClassChangeVector computeClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses)
 {
     unsigned oldSize = oldClasses.size();
     unsigned newSize = newClasses.size();
 
-    if (!oldSize) {
-        m_addedClasses = collectClasses(newClasses);
-        return;
-    }
-    if (!newSize) {
-        m_removedClasses = collectClasses(oldClasses);
-        return;
-    }
+    if (!oldSize)
+        return collectClasses(newClasses);
+    if (!newSize)
+        return collectClasses(oldClasses);
 
+    ClassChangeVector changedClasses;
+
     BitVector remainingClassBits;
     remainingClassBits.ensureSize(oldSize);
     // Class vectors tend to be very short. This is faster than using a hash table.
@@ -70,21 +70,25 @@
         }
         if (foundFromBoth)
             continue;
-        m_addedClasses.append(newClasses[i].impl());
+        changedClasses.append(newClasses[i].impl());
     }
     for (unsigned i = 0; i < oldSize; ++i) {
         // If the bit is not set the the corresponding class has been removed.
         if (remainingClassBits.quickGet(i))
             continue;
-        m_removedClasses.append(oldClasses[i].impl());
+        changedClasses.append(oldClasses[i].impl());
     }
+
+    return changedClasses;
 }
 
-void ClassChangeInvalidation::invalidateStyle(const ClassChangeVector& changedClasses)
+void ClassChangeInvalidation::invalidateStyle(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses)
 {
+    auto changedClasses = computeClassChange(oldClasses, newClasses);
+
     auto& ruleSets = m_element.styleResolver().ruleSets();
 
-    Vector<AtomicStringImpl*, 4> changedClassesAffectingStyle;
+    ClassChangeVector changedClassesAffectingStyle;
     for (auto* changedClass : changedClasses) {
         if (ruleSets.features().classesInRules.contains(changedClass))
             changedClassesAffectingStyle.append(changedClass);
@@ -107,6 +111,13 @@
         auto* ancestorClassRules = ruleSets.ancestorClassRules(changedClass);
         if (!ancestorClassRules)
             continue;
+        m_descendantInvalidationRuleSets.append(ancestorClassRules);
+    }
+}
+
+void ClassChangeInvalidation::invalidateDescendantStyle()
+{
+    for (auto* ancestorClassRules : m_descendantInvalidationRuleSets) {
         StyleInvalidationAnalysis invalidationAnalysis(*ancestorClassRules);
         invalidationAnalysis.invalidateStyle(m_element);
     }

Modified: releases/WebKitGTK/webkit-2.12/Source/WebCore/style/ClassChangeInvalidation.h (199367 => 199368)


--- releases/WebKitGTK/webkit-2.12/Source/WebCore/style/ClassChangeInvalidation.h	2016-04-12 16:46:37 UTC (rev 199367)
+++ releases/WebKitGTK/webkit-2.12/Source/WebCore/style/ClassChangeInvalidation.h	2016-04-12 16:50:02 UTC (rev 199368)
@@ -44,18 +44,13 @@
     ~ClassChangeInvalidation();
 
 private:
-    using ClassChangeVector = Vector<AtomicStringImpl*, 4>;
+    void invalidateStyle(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses);
+    void invalidateDescendantStyle();
 
-    void computeClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses);
-    void invalidateStyle(const ClassChangeVector&);
-
-    static ClassChangeVector collectClasses(const SpaceSplitString&);
-
     const bool m_isEnabled;
     Element& m_element;
 
-    ClassChangeVector m_addedClasses;
-    ClassChangeVector m_removedClasses;
+    Vector<const RuleSet*, 4> m_descendantInvalidationRuleSets;
 };
 
 inline ClassChangeInvalidation::ClassChangeInvalidation(Element& element, const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses)
@@ -65,15 +60,15 @@
 {
     if (!m_isEnabled)
         return;
-    computeClassChange(oldClasses, newClasses);
-    invalidateStyle(m_removedClasses);
+    invalidateStyle(oldClasses, newClasses);
+    invalidateDescendantStyle();
 }
 
 inline ClassChangeInvalidation::~ClassChangeInvalidation()
 {
     if (!m_isEnabled)
         return;
-    invalidateStyle(m_addedClasses);
+    invalidateDescendantStyle();
 }
     
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to