Title: [208610] trunk
Revision
208610
Author
[email protected]
Date
2016-11-11 13:59:33 -0800 (Fri, 11 Nov 2016)

Log Message

Shadow DOM: Toggling class in `.class ::slotted(*)` does not trigger style recalc
https://bugs.webkit.org/show_bug.cgi?id=160864

Reviewed by Ryosuke Niwa.

Source/WebCore:

Also fix similar issue with ::host

Test: fast/shadow-dom/css-scoping-host-and-slotted-context-invalidation.html

* css/StyleInvalidationAnalysis.cpp:
(WebCore::StyleInvalidationAnalysis::invalidateIfNeeded):

    If we have ::slotted rules and encounter a <slot>, invalidate the slotted host children.

(WebCore::StyleInvalidationAnalysis::invalidateStyle):

    Invalidate the shadow host if we have ::host rules.

* css/StyleInvalidationAnalysis.h:
* dom/InlineStyleSheetOwner.cpp:
(WebCore::InlineStyleSheetOwner::createSheet):

    Fix a bug where it was possible to mutate stylesheets in the inline stylesheet cache.
    The included test covers this.

* style/StyleScope.cpp:
(WebCore::Style::Scope::updateActiveStyleSheets):

    Handle the full invalidation case.

LayoutTests:

* fast/shadow-dom/css-scoping-host-and-slotted-context-invalidation-expected.html: Added.
* fast/shadow-dom/css-scoping-host-and-slotted-context-invalidation.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (208609 => 208610)


--- trunk/LayoutTests/ChangeLog	2016-11-11 21:57:42 UTC (rev 208609)
+++ trunk/LayoutTests/ChangeLog	2016-11-11 21:59:33 UTC (rev 208610)
@@ -1,3 +1,13 @@
+2016-11-11  Antti Koivisto  <[email protected]>
+
+        Shadow DOM: Toggling class in `.class ::slotted(*)` does not trigger style recalc
+        https://bugs.webkit.org/show_bug.cgi?id=160864
+
+        Reviewed by Ryosuke Niwa.
+
+        * fast/shadow-dom/css-scoping-host-and-slotted-context-invalidation-expected.html: Added.
+        * fast/shadow-dom/css-scoping-host-and-slotted-context-invalidation.html: Added.
+
 2016-11-11  Eric Carlson  <[email protected]>
 
         [MediaStream] defer resolution of getUserMedia promise made in a background tab
@@ -1201,6 +1211,7 @@
         * fast/shadow-dom/css-scoping-slot-with-id-expected.html: Added.
         * fast/shadow-dom/css-scoping-slot-with-id.html: Added.
 
+
 2016-11-04  Brady Eidson  <[email protected]>
 
         IndexedDB 2.0: Use IDB-specific exceptions in places where the generic exceptions are currently used.

Added: trunk/LayoutTests/fast/shadow-dom/css-scoping-host-and-slotted-context-invalidation-expected.html (0 => 208610)


--- trunk/LayoutTests/fast/shadow-dom/css-scoping-host-and-slotted-context-invalidation-expected.html	                        (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/css-scoping-host-and-slotted-context-invalidation-expected.html	2016-11-11 21:59:33 UTC (rev 208610)
@@ -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/css-scoping-host-and-slotted-context-invalidation.html (0 => 208610)


--- trunk/LayoutTests/fast/shadow-dom/css-scoping-host-and-slotted-context-invalidation.html	                        (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/css-scoping-host-and-slotted-context-invalidation.html	2016-11-11 21:59:33 UTC (rev 208610)
@@ -0,0 +1,83 @@
+<!DOCTYPE html>
+<body>
+<p>Test passes if you see a single 100px by 100px green box below.</p>
+<div id="t1">
+    <span>FAIL</span>
+</div>
+<div id="t2">
+    <span slot="second">FAIL</span>
+</div>
+<div id="t3">
+    <span>FAIL</span>
+</div>
+<div id="t4">
+    <span>FAIL</span>
+</div>
+<div id="t5">
+    <span>FAIL</span>
+</div>
+<script>
+
+function attachShadow(host)
+{
+    const shadow = host.attachShadow({mode: 'closed'});
+    shadow.innerHTML = `
+    <style>
+    :host {
+        width: 100px;
+        height: 20px;
+        background: green;
+        color: red;
+    }
+    </style>
+    <div><slot></slot></div>
+    <div id="second-parent"><slot name="second"></slot></div>
+    `;
+    return shadow;
+}
+
+{
+    const host = document.querySelector('#t1');
+    const shadow = attachShadow(host);
+    const style = shadow.querySelector('style');
+    style.sheet.insertRule(".selected ::slotted(*) { color: green }");
+    getComputedStyle(host.querySelector('span')).backgroundColor;
+    const div = shadow.querySelector('div');
+    div.className = 'selected';
+}
+
+{
+    const host = document.querySelector('#t2');
+    const shadow = attachShadow(host);
+    getComputedStyle(host.querySelector('span')).backgroundColor;
+    const style = shadow.querySelector('style');
+    style.sheet.insertRule("#second-parent ::slotted(*) { color: green }");
+}
+
+{
+    const host = document.querySelector('#t3');
+    const shadow = attachShadow(host);
+    getComputedStyle(host.querySelector('span')).backgroundColor;
+    const style = document.createElement("style");
+    style.textContent = "div ::slotted(*) { color: green }";
+    shadow.appendChild(style);
+}
+
+{
+    const host = document.querySelector('#t4');
+    const shadow = attachShadow(host);
+    getComputedStyle(host.querySelector('span')).backgroundColor;
+    const style = shadow.querySelector('style');
+    style.sheet.insertRule(":host { color: green }", 1);
+}
+
+{
+    const host = document.querySelector('#t5');
+    const shadow = attachShadow(host);
+    getComputedStyle(host.querySelector('span')).backgroundColor;
+    const style = document.createElement("style");
+    style.textContent = ":host(div) { color: green }";
+    shadow.appendChild(style)
+}
+
+</script>

Modified: trunk/Source/WebCore/ChangeLog (208609 => 208610)


--- trunk/Source/WebCore/ChangeLog	2016-11-11 21:57:42 UTC (rev 208609)
+++ trunk/Source/WebCore/ChangeLog	2016-11-11 21:59:33 UTC (rev 208610)
@@ -1,3 +1,35 @@
+2016-11-11  Antti Koivisto  <[email protected]>
+
+        Shadow DOM: Toggling class in `.class ::slotted(*)` does not trigger style recalc
+        https://bugs.webkit.org/show_bug.cgi?id=160864
+
+        Reviewed by Ryosuke Niwa.
+
+        Also fix similar issue with ::host
+
+        Test: fast/shadow-dom/css-scoping-host-and-slotted-context-invalidation.html
+
+        * css/StyleInvalidationAnalysis.cpp:
+        (WebCore::StyleInvalidationAnalysis::invalidateIfNeeded):
+
+            If we have ::slotted rules and encounter a <slot>, invalidate the slotted host children.
+
+        (WebCore::StyleInvalidationAnalysis::invalidateStyle):
+
+            Invalidate the shadow host if we have ::host rules.
+
+        * css/StyleInvalidationAnalysis.h:
+        * dom/InlineStyleSheetOwner.cpp:
+        (WebCore::InlineStyleSheetOwner::createSheet):
+
+            Fix a bug where it was possible to mutate stylesheets in the inline stylesheet cache.
+            The included test covers this.
+
+        * style/StyleScope.cpp:
+        (WebCore::Style::Scope::updateActiveStyleSheets):
+
+            Handle the full invalidation case.
+
 2016-11-11  Brady Eidson  <[email protected]>
 
         IndexedDB 2.0: "close pending flag" and firing blocked events all need fixing.

Modified: trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp (208609 => 208610)


--- trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp	2016-11-11 21:57:42 UTC (rev 208609)
+++ trunk/Source/WebCore/css/StyleInvalidationAnalysis.cpp	2016-11-11 21:59:33 UTC (rev 208610)
@@ -30,6 +30,7 @@
 #include "Document.h"
 #include "ElementIterator.h"
 #include "ElementRuleCollector.h"
+#include "HTMLSlotElement.h"
 #include "SelectorFilter.h"
 #include "ShadowRoot.h"
 #include "StyleRuleImport.h"
@@ -103,6 +104,17 @@
             element.invalidateStyleForSubtree();
     }
 
+    bool shouldCheckForSlots = !m_ruleSet.slottedPseudoElementRules().isEmpty() && !m_didInvalidateHostChildren;
+    if (shouldCheckForSlots && is<HTMLSlotElement>(element)) {
+        auto* containingShadowRoot = element.containingShadowRoot();
+        if (containingShadowRoot && containingShadowRoot->host()) {
+            for (auto& possiblySlotted : childrenOfType<Element>(*containingShadowRoot->host()))
+                possiblySlotted.invalidateStyle();
+        }
+        // No need to do this again.
+        m_didInvalidateHostChildren = true;
+    }
+
     switch (element.styleValidity()) {
     case Style::Validity::Valid: {
         ElementRuleCollector ruleCollector(element, m_ruleSet, filter);
@@ -117,6 +129,8 @@
         return CheckDescendants::Yes;
     case Style::Validity::SubtreeInvalid:
     case Style::Validity::SubtreeAndRenderersInvalid:
+        if (shouldCheckForSlots)
+            return CheckDescendants::Yes;
         return CheckDescendants::No;
     }
     ASSERT_NOT_REACHED();
@@ -172,6 +186,9 @@
 {
     ASSERT(!m_dirtiesAllStyle);
 
+    if (!m_ruleSet.hostPseudoClassRules().isEmpty() && shadowRoot.host())
+        shadowRoot.host()->invalidateStyle();
+
     for (auto& child : childrenOfType<Element>(shadowRoot)) {
         SelectorFilter filter;
         invalidateStyleForTree(child, &filter);

Modified: trunk/Source/WebCore/css/StyleInvalidationAnalysis.h (208609 => 208610)


--- trunk/Source/WebCore/css/StyleInvalidationAnalysis.h	2016-11-11 21:57:42 UTC (rev 208609)
+++ trunk/Source/WebCore/css/StyleInvalidationAnalysis.h	2016-11-11 21:59:33 UTC (rev 208610)
@@ -58,6 +58,7 @@
     const RuleSet& m_ruleSet;
     bool m_dirtiesAllStyle { false };
     bool m_hasShadowPseudoElementRulesInAuthorSheet { false };
+    bool m_didInvalidateHostChildren { false };
 };
 
 }

Modified: trunk/Source/WebCore/dom/InlineStyleSheetOwner.cpp (208609 => 208610)


--- trunk/Source/WebCore/dom/InlineStyleSheetOwner.cpp	2016-11-11 21:57:42 UTC (rev 208609)
+++ trunk/Source/WebCore/dom/InlineStyleSheetOwner.cpp	2016-11-11 21:59:33 UTC (rev 208610)
@@ -213,12 +213,15 @@
     contents->checkLoaded();
 
     if (cacheKey && contents->isCacheable()) {
+        m_sheet->contents().addedToMemoryCache();
         inlineStyleSheetCache().add(*cacheKey, &m_sheet->contents());
 
         // Prevent pathological growth.
         const size_t maximumInlineStyleSheetCacheSize = 50;
-        if (inlineStyleSheetCache().size() > maximumInlineStyleSheetCacheSize)
+        if (inlineStyleSheetCache().size() > maximumInlineStyleSheetCacheSize) {
+            inlineStyleSheetCache().begin()->value->removedFromMemoryCache();
             inlineStyleSheetCache().remove(inlineStyleSheetCache().begin());
+        }
     }
 }
 

Modified: trunk/Source/WebCore/style/StyleScope.cpp (208609 => 208610)


--- trunk/Source/WebCore/style/StyleScope.cpp	2016-11-11 21:57:42 UTC (rev 208609)
+++ trunk/Source/WebCore/style/StyleScope.cpp	2016-11-11 21:59:33 UTC (rev 208610)
@@ -407,10 +407,19 @@
             m_usesStyleBasedEditability = true;
     }
 
+    // FIXME: Move this code somewhere else.
     if (requiresFullStyleRecalc) {
         if (m_shadowRoot) {
             for (auto& shadowChild : childrenOfType<Element>(*m_shadowRoot))
                 shadowChild.invalidateStyleForSubtree();
+            if (m_shadowRoot->host()) {
+                if (!resolver().ruleSets().authorStyle().hostPseudoClassRules().isEmpty())
+                    m_shadowRoot->host()->invalidateStyle();
+                if (!resolver().ruleSets().authorStyle().slottedPseudoElementRules().isEmpty()) {
+                    for (auto& shadowChild : childrenOfType<Element>(*m_shadowRoot->host()))
+                        shadowChild.invalidateStyle();
+                }
+            }
         } else
             m_document.scheduleForcedStyleRecalc();
     }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to