Stop copying author shadow pseudo rules into shadow tree style resolver
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Oct 2016 10:24:07 +0000 (10:24 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 11 Oct 2016 10:24:07 +0000 (10:24 +0000)
https://bugs.webkit.org/show_bug.cgi?id=163232

Reviewed by Darin Adler.

* css/ElementRuleCollector.cpp:
(WebCore::ElementRuleCollector::collectMatchingRules):
(WebCore::ElementRuleCollector::matchAuthorRules):
(WebCore::ElementRuleCollector::matchAuthorShadowPseudoElementRules):

    If we are resolving a user agent shadow tree also look up pseudo element rules from the host scope author sheet.
    This is needed to keep web exposed ::-webkit-foo pseudo elements working.

(WebCore::ElementRuleCollector::collectMatchingShadowPseudoElementRules):

    Factor to a function.

* css/ElementRuleCollector.h:
* css/RuleSet.cpp:
(WebCore::RuleSet::copyShadowPseudoElementRulesFrom): Deleted.
* css/RuleSet.h:
* dom/Document.cpp:
(WebCore::Document::userAgentShadowTreeStyleResolver):
* style/StyleScope.cpp:
(WebCore::Style::Scope::updateStyleResolver):

    No need to awkwardly copy these rules anymore.

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@207077 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Source/WebCore/ChangeLog
Source/WebCore/css/ElementRuleCollector.cpp
Source/WebCore/css/ElementRuleCollector.h
Source/WebCore/css/RuleSet.cpp
Source/WebCore/css/RuleSet.h
Source/WebCore/dom/Document.cpp
Source/WebCore/style/StyleScope.cpp

index 8dcede1..47c8402 100644 (file)
@@ -1,3 +1,33 @@
+2016-10-10  Antti Koivisto  <antti@apple.com>
+
+        Stop copying author shadow pseudo rules into shadow tree style resolver
+        https://bugs.webkit.org/show_bug.cgi?id=163232
+
+        Reviewed by Darin Adler.
+
+        * css/ElementRuleCollector.cpp:
+        (WebCore::ElementRuleCollector::collectMatchingRules):
+        (WebCore::ElementRuleCollector::matchAuthorRules):
+        (WebCore::ElementRuleCollector::matchAuthorShadowPseudoElementRules):
+
+            If we are resolving a user agent shadow tree also look up pseudo element rules from the host scope author sheet.
+            This is needed to keep web exposed ::-webkit-foo pseudo elements working.
+
+        (WebCore::ElementRuleCollector::collectMatchingShadowPseudoElementRules):
+
+            Factor to a function.
+
+        * css/ElementRuleCollector.h:
+        * css/RuleSet.cpp:
+        (WebCore::RuleSet::copyShadowPseudoElementRulesFrom): Deleted.
+        * css/RuleSet.h:
+        * dom/Document.cpp:
+        (WebCore::Document::userAgentShadowTreeStyleResolver):
+        * style/StyleScope.cpp:
+        (WebCore::Style::Scope::updateStyleResolver):
+
+            No need to awkwardly copy these rules anymore.
+
 2016-10-11  Chris Dumez  <cdumez@apple.com>
 
         Update IDBVersionChangeEvent to stop using legacy [ConstructorTemplate=Event]
index e6c3910..255c8fc 100644 (file)
@@ -143,17 +143,9 @@ void ElementRuleCollector::collectMatchingRules(const MatchRequest& matchRequest
     ASSERT(matchRequest.ruleSet);
     ASSERT_WITH_MESSAGE(!(m_mode == SelectorChecker::Mode::CollectingRulesIgnoringVirtualPseudoElements && m_pseudoStyleRequest.pseudoId != NOPSEUDO), "When in StyleInvalidation or SharingRules, SelectorChecker does not try to match the pseudo ID. While ElementRuleCollector supports matching a particular pseudoId in this case, this would indicate a error at the call site since matching a particular element should be unnecessary.");
 
-#if ENABLE(VIDEO_TRACK)
-    if (m_element.isWebVTTElement())
-        collectMatchingRulesForList(matchRequest.ruleSet->cuePseudoRules(), matchRequest, ruleRange);
-#endif
-
     auto* shadowRoot = m_element.containingShadowRoot();
-    if (shadowRoot && shadowRoot->mode() == ShadowRoot::Mode::UserAgent) {
-        const AtomicString& pseudoId = m_element.shadowPseudoId();
-        if (!pseudoId.isEmpty())
-            collectMatchingRulesForList(matchRequest.ruleSet->shadowPseudoElementRules(pseudoId.impl()), matchRequest, ruleRange);
-    }
+    if (shadowRoot && shadowRoot->mode() == ShadowRoot::Mode::UserAgent)
+        collectMatchingShadowPseudoElementRules(matchRequest, ruleRange);
 
     // We need to collect the rules for id, class, tag, and everything else into a buffer and
     // then sort the buffer.
@@ -226,9 +218,24 @@ void ElementRuleCollector::matchAuthorRules(bool includeEmptyRules)
     if (m_element.shadowRoot())
         matchHostPseudoClassRules(matchRequest, ruleRange);
 
+    if (m_element.isInShadowTree())
+        matchAuthorShadowPseudoElementRules(matchRequest, ruleRange);
+
     sortAndTransferMatchedRules();
 }
 
+void ElementRuleCollector::matchAuthorShadowPseudoElementRules(const MatchRequest& matchRequest, StyleResolver::RuleRange& ruleRange)
+{
+    ASSERT(m_element.isInShadowTree());
+    auto& shadowRoot = *m_element.containingShadowRoot();
+    if (shadowRoot.mode() != ShadowRoot::Mode::UserAgent)
+        return;
+    // Look up shadow pseudo elements also from the host scope author style as they are web-exposed.
+    auto& hostAuthorRules = Style::Scope::forNode(*shadowRoot.host()).resolver().ruleSets().authorStyle();
+    MatchRequest hostAuthorRequest { &hostAuthorRules, matchRequest.includeEmptyRules };
+    collectMatchingShadowPseudoElementRules(hostAuthorRequest, ruleRange);
+}
+
 void ElementRuleCollector::matchHostPseudoClassRules(MatchRequest& matchRequest, StyleResolver::RuleRange& ruleRange)
 {
     ASSERT(m_element.shadowRoot());
@@ -284,6 +291,22 @@ void ElementRuleCollector::matchSlottedPseudoElementRules(MatchRequest& matchReq
     }
 }
 
+void ElementRuleCollector::collectMatchingShadowPseudoElementRules(const MatchRequest& matchRequest, StyleResolver::RuleRange& ruleRange)
+{
+    ASSERT(matchRequest.ruleSet);
+    ASSERT(m_element.containingShadowRoot()->mode() == ShadowRoot::Mode::UserAgent);
+
+    auto& rules = *matchRequest.ruleSet;
+#if ENABLE(VIDEO_TRACK)
+    // FXIME: WebVTT should not be done by styling UA shadow trees like this.
+    if (m_element.isWebVTTElement())
+        collectMatchingRulesForList(rules.cuePseudoRules(), matchRequest, ruleRange);
+#endif
+    auto& pseudoId = m_element.shadowPseudoId();
+    if (!pseudoId.isEmpty())
+        collectMatchingRulesForList(rules.shadowPseudoElementRules(pseudoId.impl()), matchRequest, ruleRange);
+}
+
 std::unique_ptr<RuleSet::RuleDataVector> ElementRuleCollector::collectSlottedPseudoElementRulesForSlot(bool includeEmptyRules)
 {
     ASSERT(is<HTMLSlotElement>(m_element));
index e1f8074..7940948 100644 (file)
@@ -76,8 +76,11 @@ private:
     void addElementStyleProperties(const StyleProperties*, bool isCacheable = true);
 
     void matchUARules(RuleSet*);
+    void matchAuthorShadowPseudoElementRules(const MatchRequest&, StyleResolver::RuleRange&);
     void matchHostPseudoClassRules(MatchRequest&, StyleResolver::RuleRange&);
     void matchSlottedPseudoElementRules(MatchRequest&, StyleResolver::RuleRange&);
+
+    void collectMatchingShadowPseudoElementRules(const MatchRequest&, StyleResolver::RuleRange&);
     std::unique_ptr<RuleSet::RuleDataVector> collectSlottedPseudoElementRulesForSlot(bool includeEmptyRules);
 
     void collectMatchingRules(const MatchRequest&, StyleResolver::RuleRange&);
index 72f6829..cca2bc3 100644 (file)
@@ -394,18 +394,6 @@ bool RuleSet::hasShadowPseudoElementRules() const
     return false;
 }
 
-void RuleSet::copyShadowPseudoElementRulesFrom(const RuleSet& other)
-{
-    for (auto& keyValuePair : other.m_shadowPseudoElementRules)
-        m_shadowPseudoElementRules.add(keyValuePair.key, std::make_unique<RuleDataVector>(*keyValuePair.value));
-
-#if ENABLE(VIDEO_TRACK)
-    // FIXME: We probably shouldn't treat WebVTT as author stylable user agent shadow tree.
-    for (auto& cue : other.m_cuePseudoRules)
-        m_cuePseudoRules.append(cue);
-#endif
-}
-
 static inline void shrinkMapVectorsToFit(RuleSet::AtomRuleMap& map)
 {
     for (auto& vector : map.values())
index 7aee581..9909173 100644 (file)
@@ -192,7 +192,6 @@ public:
     unsigned ruleCount() const { return m_ruleCount; }
 
     bool hasShadowPseudoElementRules() const;
-    void copyShadowPseudoElementRulesFrom(const RuleSet&);
 
 private:
     void addChildRules(const Vector<RefPtr<StyleRuleBase>>&, const MediaQueryEvaluator& medium, StyleResolver*, bool hasDocumentSecurityOrigin, bool isInitiatingElementInUserAgentShadowTree, AddRuleFlags);
index d0ba9bf..e182519 100644 (file)
@@ -2144,15 +2144,8 @@ void Document::pageSizeAndMarginsInPixels(int pageIndex, IntSize& pageSize, int&
 
 StyleResolver& Document::userAgentShadowTreeStyleResolver()
 {
-    if (!m_userAgentShadowTreeStyleResolver) {
+    if (!m_userAgentShadowTreeStyleResolver)
         m_userAgentShadowTreeStyleResolver = std::make_unique<StyleResolver>(*this);
-
-        // FIXME: Filter out shadow pseudo elements we don't want to expose to authors.
-        auto& documentAuthorStyle = styleScope().resolver().ruleSets().authorStyle();
-        if (documentAuthorStyle.hasShadowPseudoElementRules())
-            m_userAgentShadowTreeStyleResolver->ruleSets().authorStyle().copyShadowPseudoElementRulesFrom(documentAuthorStyle);
-    }
-
     return *m_userAgentShadowTreeStyleResolver;
 }
 
index 05d8214..9d74dfb 100644 (file)
@@ -404,14 +404,6 @@ void Scope::updateStyleResolver(Vector<RefPtr<CSSStyleSheet>>& activeStyleSheets
         newStyleSheets.appendRange(activeStyleSheets.begin() + firstNewIndex, activeStyleSheets.end());
         styleResolver.appendAuthorStyleSheets(newStyleSheets);
     }
-
-    if (!m_shadowRoot) {
-        auto& userAgentShadowTreeStyleResolver = m_document.userAgentShadowTreeStyleResolver();
-        userAgentShadowTreeStyleResolver.ruleSets().resetAuthorStyle();
-        auto& authorRuleSet = styleResolver.ruleSets().authorStyle();
-        if (authorRuleSet.hasShadowPseudoElementRules())
-            userAgentShadowTreeStyleResolver.ruleSets().authorStyle().copyShadowPseudoElementRulesFrom(authorRuleSet);
-    }
 }
 
 const Vector<RefPtr<CSSStyleSheet>> Scope::activeStyleSheetsForInspector() const