Title: [202227] trunk
Revision
202227
Author
[email protected]
Date
2016-06-20 01:52:10 -0700 (Mon, 20 Jun 2016)

Log Message

Updating class name of a shadow host does not update the style applied by :host()
https://bugs.webkit.org/show_bug.cgi?id=158900
<rdar://problem/26883707>

Reviewed by Simon Fraser.

Source/WebCore:

Test: fast/shadow-dom/shadow-host-style-update.html

Teach style invalidation optimization code about :host.

* style/AttributeChangeInvalidation.cpp:
(WebCore::Style::mayBeAffectedByHostStyle):
(WebCore::Style::AttributeChangeInvalidation::invalidateStyle):
* style/ClassChangeInvalidation.cpp:
(WebCore::Style::computeClassChange):
(WebCore::Style::mayBeAffectedByHostStyle):
(WebCore::Style::ClassChangeInvalidation::invalidateStyle):
* style/IdChangeInvalidation.cpp:
(WebCore::Style::mayBeAffectedByHostStyle):
(WebCore::Style::IdChangeInvalidation::invalidateStyle):

LayoutTests:

* fast/shadow-dom/shadow-host-style-update-expected.html: Added.
* fast/shadow-dom/shadow-host-style-update.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (202226 => 202227)


--- trunk/LayoutTests/ChangeLog	2016-06-20 07:07:04 UTC (rev 202226)
+++ trunk/LayoutTests/ChangeLog	2016-06-20 08:52:10 UTC (rev 202227)
@@ -1,3 +1,14 @@
+2016-06-19  Antti Koivisto  <[email protected]>
+
+        Updating class name of a shadow host does not update the style applied by :host()
+        https://bugs.webkit.org/show_bug.cgi?id=158900
+        <rdar://problem/26883707>
+
+        Reviewed by Simon Fraser.
+
+        * fast/shadow-dom/shadow-host-style-update-expected.html: Added.
+        * fast/shadow-dom/shadow-host-style-update.html: Added.
+
 2016-06-19  Alexey Proskuryakov  <[email protected]>
 
         Test expectation gardening.

Added: trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update-expected.html (0 => 202227)


--- trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update-expected.html	2016-06-20 08:52:10 UTC (rev 202227)
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+<body>
+    <p>Test passes if you see a single 100px by 100px green box below.</p>
+    <div style="width: 100px; height: 100px; background: green;"></div>
+</body>
+</html>

Added: trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update.html (0 => 202227)


--- trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update.html	                        (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/shadow-host-style-update.html	2016-06-20 08:52:10 UTC (rev 202227)
@@ -0,0 +1,70 @@
+<!DOCTYPE html>
+<html>
+<head>
+<style>
+.test {
+    width: 100px;
+    height: 25px;
+    background: red;
+}
+</style>
+</head>
+<body>
+<p>Test passes if you see a single 100px by 100px green box below.</p> 
+<div id="host1" class="test"></div>
+<div id="host2" class="test"></div>
+<div id="host3" class="test"></div>
+<div id="host4" class="test" attr="red"></div>
+<script>
+
+var host1 = document.getElementById('host1');
+host1.attachShadow({mode: 'closed'}).innerHTML = `
+    <style>
+    :host(.green) {
+        background: green !important;
+    }
+    </style>
+`;
+
+getComputedStyle(host1).backgroundColor;
+host1.classList.toggle('green');
+
+var host2 = document.getElementById('host2');
+host2.attachShadow({mode: 'closed'}).innerHTML = `
+    <style>
+    :host(#greenID) {
+        background: green !important;
+    }
+    </style>
+`;
+
+getComputedStyle(host2).backgroundColor;
+host2.id = 'greenID';
+
+var host3 = document.getElementById('host3');
+host3.attachShadow({mode: 'closed'}).innerHTML = `
+    <style>
+    :host([greenAttr]) {
+        background: green !important;
+    }
+    </style>
+`;
+
+getComputedStyle(host3).backgroundColor;
+host3.setAttribute('greenAttr', '');
+
+var host4 = document.getElementById('host4');
+host4.attachShadow({mode: 'closed'}).innerHTML = `
+    <style>
+    :host([attr=green]) {
+        background: green !important;
+    }
+    </style>
+`;
+
+getComputedStyle(host4).backgroundColor;
+host4.setAttribute('attr', 'green');
+
+</script>
+</body>
+</html>

Modified: trunk/Source/WebCore/ChangeLog (202226 => 202227)


--- trunk/Source/WebCore/ChangeLog	2016-06-20 07:07:04 UTC (rev 202226)
+++ trunk/Source/WebCore/ChangeLog	2016-06-20 08:52:10 UTC (rev 202227)
@@ -1,3 +1,26 @@
+2016-06-19  Antti Koivisto  <[email protected]>
+
+        Updating class name of a shadow host does not update the style applied by :host()
+        https://bugs.webkit.org/show_bug.cgi?id=158900
+        <rdar://problem/26883707>
+
+        Reviewed by Simon Fraser.
+
+        Test: fast/shadow-dom/shadow-host-style-update.html
+
+        Teach style invalidation optimization code about :host.
+
+        * style/AttributeChangeInvalidation.cpp:
+        (WebCore::Style::mayBeAffectedByHostStyle):
+        (WebCore::Style::AttributeChangeInvalidation::invalidateStyle):
+        * style/ClassChangeInvalidation.cpp:
+        (WebCore::Style::computeClassChange):
+        (WebCore::Style::mayBeAffectedByHostStyle):
+        (WebCore::Style::ClassChangeInvalidation::invalidateStyle):
+        * style/IdChangeInvalidation.cpp:
+        (WebCore::Style::mayBeAffectedByHostStyle):
+        (WebCore::Style::IdChangeInvalidation::invalidateStyle):
+
 2016-06-19  Gavin & Ellie Barraclough  <[email protected]>
 
         Remove hasStaticPropertyTable (part 5: done!)

Modified: trunk/Source/WebCore/style/AttributeChangeInvalidation.cpp (202226 => 202227)


--- trunk/Source/WebCore/style/AttributeChangeInvalidation.cpp	2016-06-20 07:07:04 UTC (rev 202226)
+++ trunk/Source/WebCore/style/AttributeChangeInvalidation.cpp	2016-06-20 08:52:10 UTC (rev 202227)
@@ -28,6 +28,7 @@
 
 #include "DocumentRuleSets.h"
 #include "ElementIterator.h"
+#include "ShadowRoot.h"
 #include "StyleInvalidationAnalysis.h"
 #include "StyleResolver.h"
 
@@ -34,6 +35,16 @@
 namespace WebCore {
 namespace Style {
 
+static bool mayBeAffectedByHostStyle(ShadowRoot& shadowRoot, bool isHTML, const QualifiedName& attributeName)
+{
+    auto& shadowRuleSets = shadowRoot.styleResolver().ruleSets();
+    if (shadowRuleSets.authorStyle()->hostPseudoClassRules().isEmpty())
+        return false;
+
+    auto& nameSet = isHTML ? shadowRuleSets.features().attributeCanonicalLocalNamesInRules : shadowRuleSets.features().attributeLocalNamesInRules;
+    return nameSet.contains(attributeName.localName().impl());
+}
+
 void AttributeChangeInvalidation::invalidateStyle(const QualifiedName& attributeName, const AtomicString& oldValue, const AtomicString& newValue)
 {
     if (newValue == oldValue)
@@ -43,8 +54,13 @@
     bool isHTML = m_element.isHTMLElement();
 
     auto& nameSet = isHTML ? ruleSets.features().attributeCanonicalLocalNamesInRules : ruleSets.features().attributeLocalNamesInRules;
-    bool shouldInvalidate = nameSet.contains(attributeName.localName().impl());
-    if (!shouldInvalidate)
+    bool mayAffectStyle = nameSet.contains(attributeName.localName().impl());
+
+    auto* shadowRoot = m_element.shadowRoot();
+    if (!mayAffectStyle && shadowRoot && mayBeAffectedByHostStyle(*shadowRoot, isHTML, attributeName))
+        mayAffectStyle = true;
+
+    if (!mayAffectStyle)
         return;
 
     if (!isHTML) {

Modified: trunk/Source/WebCore/style/ClassChangeInvalidation.cpp (202226 => 202227)


--- trunk/Source/WebCore/style/ClassChangeInvalidation.cpp	2016-06-20 07:07:04 UTC (rev 202226)
+++ trunk/Source/WebCore/style/ClassChangeInvalidation.cpp	2016-06-20 08:52:10 UTC (rev 202227)
@@ -28,6 +28,7 @@
 
 #include "DocumentRuleSets.h"
 #include "ElementChildIterator.h"
+#include "ShadowRoot.h"
 #include "SpaceSplitString.h"
 #include "StyleInvalidationAnalysis.h"
 #include "StyleResolver.h"
@@ -84,15 +85,29 @@
     return changedClasses;
 }
 
+static bool mayBeAffectedByHostStyle(ShadowRoot& shadowRoot, AtomicStringImpl* changedClass)
+{
+    auto& shadowRuleSets = shadowRoot.styleResolver().ruleSets();
+    if (shadowRuleSets.authorStyle()->hostPseudoClassRules().isEmpty())
+        return false;
+    return shadowRuleSets.features().classesInRules.contains(changedClass);
+}
+
 void ClassChangeInvalidation::invalidateStyle(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses)
 {
     auto changedClasses = computeClassChange(oldClasses, newClasses);
 
     auto& ruleSets = m_element.styleResolver().ruleSets();
+    auto* shadowRoot = m_element.shadowRoot();
 
     ClassChangeVector changedClassesAffectingStyle;
     for (auto* changedClass : changedClasses) {
-        if (ruleSets.features().classesInRules.contains(changedClass))
+        bool mayAffectStyle = ruleSets.features().classesInRules.contains(changedClass);
+
+        if (!mayAffectStyle && shadowRoot && mayBeAffectedByHostStyle(*shadowRoot, changedClass))
+            mayAffectStyle = true;
+
+        if (mayAffectStyle)
             changedClassesAffectingStyle.append(changedClass);
     };
 
@@ -99,7 +114,7 @@
     if (changedClassesAffectingStyle.isEmpty())
         return;
 
-    if (m_element.shadowRoot() && ruleSets.authorStyle()->hasShadowPseudoElementRules()) {
+    if (shadowRoot && ruleSets.authorStyle()->hasShadowPseudoElementRules()) {
         m_element.setNeedsStyleRecalc(FullStyleChange);
         return;
     }

Modified: trunk/Source/WebCore/style/IdChangeInvalidation.cpp (202226 => 202227)


--- trunk/Source/WebCore/style/IdChangeInvalidation.cpp	2016-06-20 07:07:04 UTC (rev 202226)
+++ trunk/Source/WebCore/style/IdChangeInvalidation.cpp	2016-06-20 08:52:10 UTC (rev 202227)
@@ -28,11 +28,21 @@
 
 #include "DocumentRuleSets.h"
 #include "ElementChildIterator.h"
+#include "ShadowRoot.h"
 #include "StyleResolver.h"
 
 namespace WebCore {
 namespace Style {
 
+static bool mayBeAffectedByHostStyle(ShadowRoot& shadowRoot, const AtomicString& changedId)
+{
+    auto& shadowRuleSets = shadowRoot.styleResolver().ruleSets();
+    if (shadowRuleSets.authorStyle()->hostPseudoClassRules().isEmpty())
+        return false;
+
+    return shadowRuleSets.features().idsInRules.contains(changedId.impl());
+}
+
 void IdChangeInvalidation::invalidateStyle(const AtomicString& changedId)
 {
     if (changedId.isEmpty())
@@ -41,6 +51,11 @@
     auto& ruleSets = m_element.styleResolver().ruleSets();
 
     bool mayAffectStyle = ruleSets.features().idsInRules.contains(changedId.impl());
+
+    auto* shadowRoot = m_element.shadowRoot();
+    if (!mayAffectStyle && shadowRoot && mayBeAffectedByHostStyle(*shadowRoot, changedId))
+        mayAffectStyle = true;
+
     if (!mayAffectStyle)
         return;
 
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to