Title: [276836] trunk
Revision
276836
Author
an...@apple.com
Date
2021-04-30 05:19:26 -0700 (Fri, 30 Apr 2021)

Log Message

Share style resolvers between author shadow trees without style sheets
https://bugs.webkit.org/show_bug.cgi?id=225102

Reviewed by Sam Weinig.

Source/WebCore:

Prepare for sharing style resolvers (and all the related data) between shadow trees beyond
the currently supported user agent shadow trees. This patch refactors the sharing code
and adds support for sharing resolvers for author shadow trees without style sheets.

Test: fast/shadow-dom/style-resolver-sharing.html

* dom/Document.cpp:
(WebCore::Document::userAgentShadowTreeStyleResolver): Deleted.
(WebCore::Document::didClearStyleResolver): Deleted.

Move the shared UA resolver to Style::Scope.

* dom/Document.h:
* style/StyleResolver.h:
(WebCore::Style::Resolver::wasShared const):
(WebCore::Style::Resolver::setWasShared):

Add a bit indicating if a resolver has been shared between shadow trees.

* style/StyleScope.cpp:
(WebCore::Style::Scope::resolver):
(WebCore::Style::Scope::createDocumentResolver):
(WebCore::Style::Scope::createOrFindSharedShadowTreeResolver):

Factor into a function.
Share user agent shadow tree resolver (as before) and also resolver for empty author shadow trees.

(WebCore::Style::Scope::unshareShadowTreeResolverBeforeMutation):

If we mutate an existing resolver we need to make it unavailable for sharing.

(WebCore::Style::Scope::clearResolver):
(WebCore::Style::Scope::releaseMemory):
(WebCore::Style::Scope::analyzeStyleSheetChange):

If we are about to mutate already shared resolver we need to create a new one.

(WebCore::Style::Scope::updateActiveStyleSheets):

If style sheets change and the resolver is shared always look it up again (since it can't be mutated).

(WebCore::Style::Scope::updateResolver):
(WebCore::Style::Scope::scheduleUpdate):
(WebCore::Style::Scope::insertedInDocument):
(WebCore::Style::Scope::didChangeStyleSheetEnvironment):
(WebCore::Style::Scope::documentScope):
(WebCore::Style::Scope::isForUserAgentShadowTree const):
(WebCore::Style::Scope::shouldUseSharedUserAgentShadowTreeStyleResolver const): Deleted.
(WebCore::Style::Scope::resolverIfExists): Deleted.
* style/StyleScope.h:
(WebCore::Style::Scope::resolverIfExists):
* style/StyleScopeRuleSets.h:
(WebCore::Style::ScopeRuleSets::setIsForShadowScope): Deleted.
(WebCore::Internals::dumpStyleResolvers):
* testing/Internals.h:
* testing/Internals.idl:

Testing support.

LayoutTests:

* fast/shadow-dom/style-resolver-sharing-expected.txt: Added.
* fast/shadow-dom/style-resolver-sharing.html: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/LayoutTests/ChangeLog (276835 => 276836)


--- trunk/LayoutTests/ChangeLog	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/LayoutTests/ChangeLog	2021-04-30 12:19:26 UTC (rev 276836)
@@ -1,3 +1,13 @@
+2021-04-30  Antti Koivisto  <an...@apple.com>
+
+        Share style resolvers between author shadow trees without style sheets
+        https://bugs.webkit.org/show_bug.cgi?id=225102
+
+        Reviewed by Sam Weinig.
+
+        * fast/shadow-dom/style-resolver-sharing-expected.txt: Added.
+        * fast/shadow-dom/style-resolver-sharing.html: Added.
+
 2021-04-29  Robert Jenner  <jen...@apple.com>
 
         [macOS-wk2] LayoutTest/http/tests/websocket/tests/hybi/inspector/binary.html is a flaky failure

Added: trunk/LayoutTests/fast/shadow-dom/style-resolver-sharing-expected.txt (0 => 276836)


--- trunk/LayoutTests/fast/shadow-dom/style-resolver-sharing-expected.txt	                        (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/style-resolver-sharing-expected.txt	2021-04-30 12:19:26 UTC (rev 276836)
@@ -0,0 +1,26 @@
+Verify that shadow roots with identical styles share style resolvers (have equal identifier below).
+(document resolver (identifier=0) (author rule count=0))
+(shadow root resolver (user agent) (identifier=1) (author rule count=0))
+(shadow root resolver (user agent) (identifier=1) (author rule count=0))
+(shadow root resolver (author) (identifier=2) (author rule count=0))
+(shadow root resolver (author) (identifier=2) (author rule count=0))
+(shadow root resolver (author) (identifier=2) (author rule count=0))
+(shadow root resolver (author) (identifier=2) (author rule count=0))
+(shadow root resolver (author) (identifier=3) (author rule count=1))
+(shadow root resolver (author) (identifier=4) (author rule count=1))
+(shadow root resolver (author) (identifier=5) (author rule count=1))
+(shadow root resolver (author) (identifier=6) (author rule count=1))
+
+After style mutation
+(document resolver (identifier=0) (author rule count=0))
+(shadow root resolver (user agent) (identifier=1) (author rule count=0))
+(shadow root resolver (user agent) (identifier=1) (author rule count=0))
+(shadow root resolver (author) (identifier=2) (author rule count=0))
+(shadow root resolver (author) (identifier=2) (author rule count=0))
+(shadow root resolver (author) (identifier=3) (author rule count=1))
+(shadow root resolver (author) (identifier=4) (author rule count=1))
+(shadow root resolver (author) (identifier=5) (author rule count=2))
+(shadow root resolver (author) (identifier=6) (author rule count=2))
+(shadow root resolver (author) (identifier=2) (author rule count=0))
+(shadow root resolver (author) (identifier=2) (author rule count=0))
+

Added: trunk/LayoutTests/fast/shadow-dom/style-resolver-sharing.html (0 => 276836)


--- trunk/LayoutTests/fast/shadow-dom/style-resolver-sharing.html	                        (rev 0)
+++ trunk/LayoutTests/fast/shadow-dom/style-resolver-sharing.html	2021-04-30 12:19:26 UTC (rev 276836)
@@ -0,0 +1,62 @@
+Verify that shadow roots with identical styles share style resolvers (have equal identifier below).
+<input></input>
+<textarea></textarea>
+<div id=a></div>
+<div id=b></div>
+<div id=c></div>
+<div id=d></div>
+<div id=e></div>
+<div id=f></div>
+<div id=g></div>
+<div id=h></div>
+<pre id=log></pre>
+
+<script>
+if (window.testRunner)
+    testRunner.dumpAsText();
+
+function attachShadowWithStyle(id, style)
+{
+    const element = document.querySelector("#" + id);
+    const shadow = element.attachShadow({ mode: "open" });
+    shadow.innerHTML = `
+        <style>${ style }</style>
+        <div>${ id }</div>
+    `;
+}
+
+attachShadowWithStyle("a", "");
+attachShadowWithStyle("b", "");
+attachShadowWithStyle("c", "");
+attachShadowWithStyle("d", "");
+attachShadowWithStyle("e", "div { color: green }");
+attachShadowWithStyle("f", "div { color: green }");
+attachShadowWithStyle("g", "div { color: green }");
+attachShadowWithStyle("h", "div { color: green }");
+
+if (window.internals) {
+    log.textContent += internals.dumpStyleResolvers();
+    log.textContent += "\nAfter style mutation\n"
+}
+
+c.shadowRoot.querySelector("style").textContent = "div { color: green }";
+
+{
+    const styleElement = document.createElement("style");
+    styleElement.textContent = "div { color: green }";
+    d.shadowRoot.appendChild(styleElement);
+}
+{
+    const styleElement = document.createElement("style");
+    styleElement.textContent = "div { color: blue }";
+    e.shadowRoot.appendChild(styleElement);
+}
+
+f.shadowRoot.querySelector("style").sheet.addRule("div", "color: blue");
+g.shadowRoot.querySelector("style").textContent = "";
+h.shadowRoot.querySelector("style").remove();
+
+if (window.internals)
+    log.textContent += internals.dumpStyleResolvers();
+
+</script>

Modified: trunk/Source/WebCore/ChangeLog (276835 => 276836)


--- trunk/Source/WebCore/ChangeLog	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/Source/WebCore/ChangeLog	2021-04-30 12:19:26 UTC (rev 276836)
@@ -1,3 +1,69 @@
+2021-04-30  Antti Koivisto  <an...@apple.com>
+
+        Share style resolvers between author shadow trees without style sheets
+        https://bugs.webkit.org/show_bug.cgi?id=225102
+
+        Reviewed by Sam Weinig.
+
+        Prepare for sharing style resolvers (and all the related data) between shadow trees beyond
+        the currently supported user agent shadow trees. This patch refactors the sharing code
+        and adds support for sharing resolvers for author shadow trees without style sheets.
+        
+        Test: fast/shadow-dom/style-resolver-sharing.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::userAgentShadowTreeStyleResolver): Deleted.
+        (WebCore::Document::didClearStyleResolver): Deleted.
+        
+        Move the shared UA resolver to Style::Scope.
+        
+        * dom/Document.h:
+        * style/StyleResolver.h:
+        (WebCore::Style::Resolver::wasShared const):
+        (WebCore::Style::Resolver::setWasShared):
+        
+        Add a bit indicating if a resolver has been shared between shadow trees.
+
+        * style/StyleScope.cpp:
+        (WebCore::Style::Scope::resolver):
+        (WebCore::Style::Scope::createDocumentResolver):
+        (WebCore::Style::Scope::createOrFindSharedShadowTreeResolver):
+        
+        Factor into a function.
+        Share user agent shadow tree resolver (as before) and also resolver for empty author shadow trees.
+
+        (WebCore::Style::Scope::unshareShadowTreeResolverBeforeMutation):
+        
+        If we mutate an existing resolver we need to make it unavailable for sharing.
+        
+        (WebCore::Style::Scope::clearResolver):
+        (WebCore::Style::Scope::releaseMemory):
+        (WebCore::Style::Scope::analyzeStyleSheetChange):
+        
+        If we are about to mutate already shared resolver we need to create a new one.
+        
+        (WebCore::Style::Scope::updateActiveStyleSheets):
+        
+        If style sheets change and the resolver is shared always look it up again (since it can't be mutated).
+
+        (WebCore::Style::Scope::updateResolver):
+        (WebCore::Style::Scope::scheduleUpdate):
+        (WebCore::Style::Scope::insertedInDocument):
+        (WebCore::Style::Scope::didChangeStyleSheetEnvironment):
+        (WebCore::Style::Scope::documentScope):
+        (WebCore::Style::Scope::isForUserAgentShadowTree const):
+        (WebCore::Style::Scope::shouldUseSharedUserAgentShadowTreeStyleResolver const): Deleted.
+        (WebCore::Style::Scope::resolverIfExists): Deleted.
+        * style/StyleScope.h:
+        (WebCore::Style::Scope::resolverIfExists):
+        * style/StyleScopeRuleSets.h:
+        (WebCore::Style::ScopeRuleSets::setIsForShadowScope): Deleted.
+        (WebCore::Internals::dumpStyleResolvers):
+        * testing/Internals.h:
+        * testing/Internals.idl:
+        
+        Testing support.
+
 2021-04-30  Sergio Villar Senin  <svil...@igalia.com>
 
         Nullopt in RenderFlexibleBox::layoutFlexItems in RenderFlexibleBox::layoutBlock via RenderMultiColumnFlow::layout

Modified: trunk/Source/WebCore/dom/Document.cpp (276835 => 276836)


--- trunk/Source/WebCore/dom/Document.cpp	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/Source/WebCore/dom/Document.cpp	2021-04-30 12:19:26 UTC (rev 276836)
@@ -2382,13 +2382,6 @@
     marginLeft = style->marginLeft().isAuto() ? marginLeft : intValueForLength(style->marginLeft(), width);
 }
 
-Style::Resolver& Document::userAgentShadowTreeStyleResolver()
-{
-    if (!m_userAgentShadowTreeStyleResolver)
-        m_userAgentShadowTreeStyleResolver = Style::Resolver::create(*this);
-    return *m_userAgentShadowTreeStyleResolver;
-}
-
 void Document::fontsNeedUpdate(FontSelector&)
 {
     invalidateMatchedPropertiesCacheAndForceStyleRecalc();
@@ -2403,11 +2396,6 @@
     scheduleFullStyleRebuild();
 }
 
-void Document::didClearStyleResolver()
-{
-    m_userAgentShadowTreeStyleResolver = nullptr;
-}
-
 void Document::setIsResolvingTreeStyle(bool value)
 {
     RELEASE_ASSERT(value != m_isResolvingTreeStyle);

Modified: trunk/Source/WebCore/dom/Document.h (276835 => 276836)


--- trunk/Source/WebCore/dom/Document.h	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/Source/WebCore/dom/Document.h	2021-04-30 12:19:26 UTC (rev 276836)
@@ -1315,7 +1315,6 @@
     void invalidateMatchedPropertiesCacheAndForceStyleRecalc();
 
     void didRemoveAllPendingStylesheet();
-    void didClearStyleResolver();
 
     bool inStyleRecalc() const { return m_inStyleRecalc; }
     bool inRenderTreeUpdate() const { return m_inRenderTreeUpdate; }
@@ -1464,7 +1463,7 @@
 
     void didInsertInDocumentShadowRoot(ShadowRoot&);
     void didRemoveInDocumentShadowRoot(ShadowRoot&);
-    const HashSet<ShadowRoot*>& inDocumentShadowRoots() const { return m_inDocumentShadowRoots; }
+    const ListHashSet<ShadowRoot*>& inDocumentShadowRoots() const { return m_inDocumentShadowRoots; }
 
     void attachToCachedFrame(CachedFrameBase&);
     void detachFromCachedFrame(CachedFrameBase&);
@@ -1746,8 +1745,6 @@
 
     UniqueRef<Quirks> m_quirks;
 
-    RefPtr<Style::Resolver> m_userAgentShadowTreeStyleResolver;
-
     RefPtr<DOMWindow> m_domWindow;
     WeakPtr<Document> m_contextDocument;
 
@@ -2001,7 +1998,7 @@
     WeakHashSet<MediaProducer> m_audioProducers;
     WeakPtr<SpeechRecognition> m_activeSpeechRecognition;
 
-    HashSet<ShadowRoot*> m_inDocumentShadowRoots;
+    ListHashSet<ShadowRoot*> m_inDocumentShadowRoots;
 
 #if ENABLE(WIRELESS_PLAYBACK_TARGET)
     using TargetIdToClientMap = HashMap<PlaybackTargetClientContextIdentifier, WebCore::MediaPlaybackTargetClient*>;

Modified: trunk/Source/WebCore/dom/ShadowRoot.h (276835 => 276836)


--- trunk/Source/WebCore/dom/ShadowRoot.h	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/Source/WebCore/dom/ShadowRoot.h	2021-04-30 12:19:26 UTC (rev 276836)
@@ -62,7 +62,7 @@
 
     using TreeScope::rootNode;
 
-    Style::Scope& styleScope();
+    WEBCORE_EXPORT Style::Scope& styleScope();
     StyleSheetList& styleSheets();
 
     bool resetStyleInheritance() const { return m_resetStyleInheritance; }

Modified: trunk/Source/WebCore/style/StyleResolver.h (276835 => 276836)


--- trunk/Source/WebCore/style/StyleResolver.h	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/Source/WebCore/style/StyleResolver.h	2021-04-30 12:19:26 UTC (rev 276836)
@@ -140,6 +140,9 @@
 
     InspectorCSSOMWrappers& inspectorCSSOMWrappers() { return m_inspectorCSSOMWrappers; }
 
+    bool isSharedBetweenShadowTrees() const { return m_isSharedBetweenShadowTrees; }
+    void setSharedBetweenShadowTrees() { m_isSharedBetweenShadowTrees = true; }
+
 private:
     friend class PageRuleCollector;
 
@@ -196,6 +199,8 @@
     MatchedDeclarationsCache m_matchedDeclarationsCache;
 
     bool m_matchAuthorAndUserStyles { true };
+    bool m_isSharedBetweenShadowTrees { false };
+
     // See if we still have crashes where Resolver gets deleted early.
     bool m_isDeleted { false };
 };

Modified: trunk/Source/WebCore/style/StyleScope.cpp (276835 => 276836)


--- trunk/Source/WebCore/style/StyleScope.cpp	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/Source/WebCore/style/StyleScope.cpp	2021-04-30 12:19:26 UTC (rev 276836)
@@ -74,61 +74,72 @@
     ASSERT(!hasPendingSheets());
 }
 
-bool Scope::shouldUseSharedUserAgentShadowTreeStyleResolver() const
+Resolver& Scope::resolver()
 {
-    if (!m_shadowRoot)
-        return false;
-    if (m_shadowRoot->mode() != ShadowRootMode::UserAgent)
-        return false;
-    // If we have stylesheets in the user agent shadow tree use per-scope resolver.
-    if (!m_styleSheetCandidateNodes.isEmpty())
-        return false;
-    return true;
+    if (!m_resolver) {
+        if (m_shadowRoot)
+            createOrFindSharedShadowTreeResolver();
+        else
+            createDocumentResolver();
+    }
+    return *m_resolver;
 }
 
-Resolver& Scope::resolver()
+void Scope::createDocumentResolver()
 {
-    if (shouldUseSharedUserAgentShadowTreeStyleResolver())
-        return m_document.userAgentShadowTreeStyleResolver();
+    ASSERT(!m_resolver);
+    ASSERT(!m_shadowRoot);
 
-    if (!m_resolver) {
-        SetForScope<bool> isUpdatingStyleResolver { m_isUpdatingStyleResolver, true };
+    SetForScope<bool> isUpdatingStyleResolver { m_isUpdatingStyleResolver, true };
 
-        m_resolver = Resolver::create(m_document);
+    m_resolver = Resolver::create(m_document);
 
-        if (!m_shadowRoot) {
-            m_document.fontSelector().buildStarted();
-            m_resolver->ruleSets().initializeUserStyle();
-        } else {
-            m_resolver->ruleSets().setIsForShadowScope();
-            m_resolver->ruleSets().setUsesSharedUserStyle(m_shadowRoot->mode() != ShadowRootMode::UserAgent);
-        }
+    m_document.fontSelector().buildStarted();
 
-        m_resolver->addCurrentSVGFontFaceRules();
-        m_resolver->appendAuthorStyleSheets(m_activeStyleSheets);
+    m_resolver->ruleSets().initializeUserStyle();
+    m_resolver->addCurrentSVGFontFaceRules();
+    m_resolver->appendAuthorStyleSheets(m_activeStyleSheets);
 
-        if (!m_shadowRoot)
-            m_document.fontSelector().buildCompleted();
+    m_document.fontSelector().buildCompleted();
+}
+
+void Scope::createOrFindSharedShadowTreeResolver()
+{
+    ASSERT(!m_resolver);
+    ASSERT(m_shadowRoot);
+
+    if (m_activeStyleSheets.isEmpty()) {
+        auto& sharedResolver = isForUserAgentShadowTree() ? documentScope().m_sharedUserAgentShadowTreeResolver : documentScope().m_sharedEmptyAuthorShadowTreeResolver;
+        if (!sharedResolver) {
+            sharedResolver = Resolver::create(m_document);
+            sharedResolver->ruleSets().setUsesSharedUserStyle(!isForUserAgentShadowTree());
+        } else
+            sharedResolver->setSharedBetweenShadowTrees();
+
+        m_resolver = sharedResolver;
+        return;
     }
-    ASSERT(!m_shadowRoot || &m_document == &m_shadowRoot->document());
-    ASSERT(&m_resolver->document() == &m_document);
-    return *m_resolver;
+
+    m_resolver = Resolver::create(m_document);
+
+    m_resolver->ruleSets().setUsesSharedUserStyle(!isForUserAgentShadowTree());
+    m_resolver->appendAuthorStyleSheets(m_activeStyleSheets);
 }
 
-Resolver* Scope::resolverIfExists()
+void Scope::unshareShadowTreeResolverBeforeMutation()
 {
-    if (shouldUseSharedUserAgentShadowTreeStyleResolver())
-        return &m_document.userAgentShadowTreeStyleResolver();
+    ASSERT(m_shadowRoot);
+    ASSERT(!m_resolver->isSharedBetweenShadowTrees());
 
-    return m_resolver.get();
+    auto& sharedResolver = isForUserAgentShadowTree() ? documentScope().m_sharedUserAgentShadowTreeResolver : documentScope().m_sharedEmptyAuthorShadowTreeResolver;
+    
+    if (m_resolver == sharedResolver)
+        sharedResolver = nullptr;
 }
 
 void Scope::clearResolver()
 {
     m_resolver = nullptr;
-
-    if (!m_shadowRoot)
-        m_document.didClearStyleResolver();
 }
 
 void Scope::releaseMemory()
@@ -148,6 +159,9 @@
     }
 #endif
     clearResolver();
+
+    m_sharedUserAgentShadowTreeResolver = nullptr;
+    m_sharedEmptyAuthorShadowTreeResolver = nullptr;
 }
 
 Scope& Scope::forNode(Node& node)
@@ -383,9 +397,13 @@
 {
     unsigned newStylesheetCount = newStylesheets.size();
 
-    if (!resolverIfExists())
+    auto* resolver = resolverIfExists();
+    if (!resolver)
         return { ResolverUpdateType::Reconstruct };
 
+    if (resolver->isSharedBetweenShadowTrees())
+        return { ResolverUpdateType::Reconstruct };
+
     // Find out which stylesheets are new.
     unsigned oldStylesheetCount = m_activeStyleSheets.size();
     if (newStylesheetCount < oldStylesheetCount)
@@ -452,8 +470,12 @@
     collectActiveStyleSheets(activeStyleSheets);
 
     Vector<RefPtr<CSSStyleSheet>> activeCSSStyleSheets;
-    activeCSSStyleSheets.appendVector(m_document.extensionStyleSheets().injectedAuthorStyleSheets());
-    activeCSSStyleSheets.appendVector(m_document.extensionStyleSheets().authorStyleSheetsForTesting());
+
+    if (!isForUserAgentShadowTree()) {
+        activeCSSStyleSheets.appendVector(m_document.extensionStyleSheets().injectedAuthorStyleSheets());
+        activeCSSStyleSheets.appendVector(m_document.extensionStyleSheets().authorStyleSheetsForTesting());
+    }
+
     filterEnabledNonemptyCSSStyleSheets(activeCSSStyleSheets, activeStyleSheets);
 
     auto styleSheetChange = StyleSheetChange { ResolverUpdateType::Reconstruct };
@@ -496,19 +518,25 @@
         clearResolver();
         return;
     }
-    auto& styleResolver = resolver();
 
+    if (m_shadowRoot)
+        unshareShadowTreeResolverBeforeMutation();
+
     SetForScope<bool> isUpdatingStyleResolver { m_isUpdatingStyleResolver, true };
+
     if (updateType == ResolverUpdateType::Reset) {
-        styleResolver.ruleSets().resetAuthorStyle();
-        styleResolver.appendAuthorStyleSheets(activeStyleSheets);
-    } else {
-        ASSERT(updateType == ResolverUpdateType::Additive);
-        unsigned firstNewIndex = m_activeStyleSheets.size();
-        Vector<RefPtr<CSSStyleSheet>> newStyleSheets;
-        newStyleSheets.appendRange(activeStyleSheets.begin() + firstNewIndex, activeStyleSheets.end());
-        styleResolver.appendAuthorStyleSheets(newStyleSheets);
+        m_resolver->ruleSets().resetAuthorStyle();
+        m_resolver->appendAuthorStyleSheets(activeStyleSheets);
+        return;
     }
+
+    ASSERT(updateType == ResolverUpdateType::Additive);
+    ASSERT(activeStyleSheets.size() >= m_activeStyleSheets.size());
+
+    unsigned firstNewIndex = m_activeStyleSheets.size();
+    Vector<RefPtr<CSSStyleSheet>> newStyleSheets;
+    newStyleSheets.appendRange(activeStyleSheets.begin() + firstNewIndex, activeStyleSheets.end());
+    m_resolver->appendAuthorStyleSheets(newStyleSheets);
 }
 
 const Vector<RefPtr<CSSStyleSheet>> Scope::activeStyleSheetsForInspector()
@@ -581,7 +609,7 @@
     if (!m_pendingUpdate || *m_pendingUpdate < update) {
         m_pendingUpdate = update;
         if (m_shadowRoot)
-            m_document.styleScope().m_hasDescendantWithPendingUpdate = true;
+            documentScope().m_hasDescendantWithPendingUpdate = true;
     }
 
     m_document.scheduleRenderingUpdate({ });
@@ -592,7 +620,7 @@
     if (!m_pendingUpdate)
         return;
 
-    m_document.styleScope().m_hasDescendantWithPendingUpdate = true;
+    documentScope().m_hasDescendantWithPendingUpdate = true;
     m_document.scheduleRenderingUpdate({ });
 }
 
@@ -659,6 +687,9 @@
 void Scope::didChangeStyleSheetEnvironment()
 {
     if (!m_shadowRoot) {
+        m_sharedUserAgentShadowTreeResolver = nullptr;
+        m_sharedEmptyAuthorShadowTreeResolver = nullptr;
+
         for (auto* descendantShadowRoot : m_document.inDocumentShadowRoots()) {
             // Stylesheets is author shadow roots are potentially affected.
             if (descendantShadowRoot->mode() != ShadowRootMode::UserAgent)
@@ -686,5 +717,15 @@
     return m_styleSheetsForStyleSheetList;
 }
 
+Scope& Scope::documentScope()
+{
+    return m_document.styleScope();
 }
+
+bool Scope::isForUserAgentShadowTree() const
+{
+    return m_shadowRoot && m_shadowRoot->mode() == ShadowRootMode::UserAgent;
 }
+
+}
+}

Modified: trunk/Source/WebCore/style/StyleScope.h (276835 => 276836)


--- trunk/Source/WebCore/style/StyleScope.h	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/Source/WebCore/style/StyleScope.h	2021-04-30 12:19:26 UTC (rev 276836)
@@ -119,7 +119,7 @@
 #endif
 
     WEBCORE_EXPORT Resolver& resolver();
-    Resolver* resolverIfExists();
+    Resolver* resolverIfExists() { return m_resolver.get(); }
     void clearResolver();
     void releaseMemory();
 
@@ -132,7 +132,8 @@
     static Scope* forOrdinal(Element&, ScopeOrdinal);
 
 private:
-    bool shouldUseSharedUserAgentShadowTreeStyleResolver() const;
+    Scope& documentScope();
+    bool isForUserAgentShadowTree() const;
 
     void didRemovePendingStylesheet();
 
@@ -160,6 +161,9 @@
     void invalidateStyleAfterStyleSheetChange(const StyleSheetChange&);
 
     void updateResolver(Vector<RefPtr<CSSStyleSheet>>&, ResolverUpdateType);
+    void createDocumentResolver();
+    void createOrFindSharedShadowTreeResolver();
+    void unshareShadowTreeResolverBeforeMutation();
 
     Document& m_document;
     ShadowRoot* m_shadowRoot { nullptr };
@@ -188,6 +192,10 @@
     bool m_hasDescendantWithPendingUpdate { false };
     bool m_usesStyleBasedEditability { false };
     bool m_isUpdatingStyleResolver { false };
+
+    // FIXME: These (and some things above) are only relevant for the root scope.
+    RefPtr<Resolver> m_sharedUserAgentShadowTreeResolver;
+    RefPtr<Resolver> m_sharedEmptyAuthorShadowTreeResolver;
 };
 
 inline bool Scope::hasPendingSheets() const

Modified: trunk/Source/WebCore/style/StyleScopeRuleSets.h (276835 => 276836)


--- trunk/Source/WebCore/style/StyleScopeRuleSets.h	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/Source/WebCore/style/StyleScopeRuleSets.h	2021-04-30 12:19:26 UTC (rev 276836)
@@ -69,8 +69,6 @@
 
     bool hasComplexSelectorsForStyleAttribute() const;
 
-    void setIsForShadowScope() { m_isForShadowScope = true; }
-
     void setUsesSharedUserStyle(bool b) { m_usesSharedUserStyle = b; }
     void initializeUserStyle();
 
@@ -110,7 +108,6 @@
     mutable unsigned m_userAgentMediaQueryRuleCountOnUpdate { 0 };
 
     bool m_usesSharedUserStyle { false };
-    bool m_isForShadowScope { false };
     bool m_isAuthorStyleDefined { false };
 
     // For catching <rdar://problem/53413013>

Modified: trunk/Source/WebCore/testing/Internals.cpp (276835 => 276836)


--- trunk/Source/WebCore/testing/Internals.cpp	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/Source/WebCore/testing/Internals.cpp	2021-04-30 12:19:26 UTC (rev 276836)
@@ -6296,4 +6296,39 @@
     return intersectsForTesting(convertType(type), makeSimpleRange(a), makeSimpleRange(b));
 }
 
+String Internals::dumpStyleResolvers()
+{
+    auto* document = contextDocument();
+    if (!document || !document->domWindow())
+        return { };
+
+    document->updateStyleIfNeeded();
+
+    unsigned currentIdentifier = 0;
+    HashMap<Style::Resolver*, unsigned> resolverIdentifiers;
+
+    StringBuilder result;
+
+    auto dumpResolver = [&](auto name, auto& resolver) {
+        auto identifier = resolverIdentifiers.ensure(&resolver, [&] {
+            return currentIdentifier++;
+        }).iterator->value;
+
+        result.append("(", name, " ");
+        result.append("(identifier=", identifier, ") ");
+        result.append("(author rule count=", resolver.ruleSets().authorStyle().ruleCount(), ")");
+        result.append(")\n");
+    };
+
+    dumpResolver("document resolver", document->styleScope().resolver());
+
+    for (auto* shadowRoot : document->inDocumentShadowRoots()) {
+        auto* name = shadowRoot->mode() == ShadowRootMode::UserAgent ? "shadow root resolver (user agent)" : "shadow root resolver (author)";
+        dumpResolver(name, shadowRoot->styleScope().resolver());
+    }
+
+    return result.toString();
+}
+
+
 } // namespace WebCore

Modified: trunk/Source/WebCore/testing/Internals.h (276835 => 276836)


--- trunk/Source/WebCore/testing/Internals.h	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/Source/WebCore/testing/Internals.h	2021-04-30 12:19:26 UTC (rev 276836)
@@ -1149,6 +1149,8 @@
 
     void systemBeep();
 
+    String dumpStyleResolvers();
+
 private:
     explicit Internals(Document&);
     Document* contextDocument() const;

Modified: trunk/Source/WebCore/testing/Internals.idl (276835 => 276836)


--- trunk/Source/WebCore/testing/Internals.idl	2021-04-30 11:46:09 UTC (rev 276835)
+++ trunk/Source/WebCore/testing/Internals.idl	2021-04-30 12:19:26 UTC (rev 276836)
@@ -1029,4 +1029,6 @@
     boolean rangeIntersectsRange(AbstractRange outerRange, AbstractRange innerRange, optional TreeType tree = "Tree");
 
     undefined systemBeep();
+
+    DOMString dumpStyleResolvers();
 };
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to