Title: [283488] trunk/Source/WebCore
Revision
283488
Author
[email protected]
Date
2021-10-03 23:37:45 -0700 (Sun, 03 Oct 2021)

Log Message

Move RuleSet builder to a file of its own
https://bugs.webkit.org/show_bug.cgi?id=231137

Reviewed by Alan Bujtas.

There is quite a bit of code for it.

There is lots of room for refactoring and cleanups here. This patch does none of it.

* Sources.txt:
* WebCore.xcodeproj/project.pbxproj:
* style/RuleSet.cpp:
(WebCore::Style::RuleSet::addRule):
(WebCore::Style::RuleSet::addRulesFromSheet):
(WebCore::Style::RuleSet::Builder::addChildRules): Deleted.
(WebCore::Style::RuleSet::Builder::addRulesFromSheet): Deleted.
(WebCore::Style::RuleSet::Builder::~Builder): Deleted.
(WebCore::Style::RuleSet::Builder::addStyleRule): Deleted.
(WebCore::Style::RuleSet::Builder::registerLayers): Deleted.
(WebCore::Style::RuleSet::Builder::pushCascadeLayer): Deleted.
(WebCore::Style::RuleSet::Builder::popCascadeLayer): Deleted.
(WebCore::Style::RuleSet::Builder::updateCascadeLayerOrder): Deleted.
(WebCore::Style::RuleSet::Builder::addMutatingRulesToResolver): Deleted.
(WebCore::Style::RuleSet::MediaQueryCollector::pushAndEvaluate): Deleted.
(WebCore::Style::RuleSet::MediaQueryCollector::pop): Deleted.
(WebCore::Style::RuleSet::MediaQueryCollector::didMutateResolver): Deleted.
(WebCore::Style::RuleSet::MediaQueryCollector::addRuleIfNeeded): Deleted.

MediaQueryCollector (an implementation detail of the Builder) moves too.

* style/RuleSet.h:
* style/RuleSetBuilder.cpp: Added.
(WebCore::Style::RuleSetBuilder::~RuleSetBuilder):
(WebCore::Style::RuleSetBuilder::addChildRules):
(WebCore::Style::RuleSetBuilder::addRulesFromSheet):
(WebCore::Style::RuleSetBuilder::addStyleRule):
(WebCore::Style::RuleSetBuilder::registerLayers):
(WebCore::Style::RuleSetBuilder::pushCascadeLayer):
(WebCore::Style::RuleSetBuilder::popCascadeLayer):
(WebCore::Style::RuleSetBuilder::updateCascadeLayerOrder):
(WebCore::Style::RuleSetBuilder::addMutatingRulesToResolver):
(WebCore::Style::RuleSetMediaQueryCollector::pushAndEvaluate):
(WebCore::Style::RuleSetMediaQueryCollector::pop):
(WebCore::Style::RuleSetMediaQueryCollector::didMutateResolver):
(WebCore::Style::RuleSetMediaQueryCollector::addRuleIfNeeded):
* style/RuleSetBuilder.h: Added.

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (283487 => 283488)


--- trunk/Source/WebCore/ChangeLog	2021-10-04 05:37:08 UTC (rev 283487)
+++ trunk/Source/WebCore/ChangeLog	2021-10-04 06:37:45 UTC (rev 283488)
@@ -1,3 +1,52 @@
+2021-10-03  Antti Koivisto  <[email protected]>
+
+        Move RuleSet builder to a file of its own
+        https://bugs.webkit.org/show_bug.cgi?id=231137
+
+        Reviewed by Alan Bujtas.
+
+        There is quite a bit of code for it.
+
+        There is lots of room for refactoring and cleanups here. This patch does none of it.
+
+        * Sources.txt:
+        * WebCore.xcodeproj/project.pbxproj:
+        * style/RuleSet.cpp:
+        (WebCore::Style::RuleSet::addRule):
+        (WebCore::Style::RuleSet::addRulesFromSheet):
+        (WebCore::Style::RuleSet::Builder::addChildRules): Deleted.
+        (WebCore::Style::RuleSet::Builder::addRulesFromSheet): Deleted.
+        (WebCore::Style::RuleSet::Builder::~Builder): Deleted.
+        (WebCore::Style::RuleSet::Builder::addStyleRule): Deleted.
+        (WebCore::Style::RuleSet::Builder::registerLayers): Deleted.
+        (WebCore::Style::RuleSet::Builder::pushCascadeLayer): Deleted.
+        (WebCore::Style::RuleSet::Builder::popCascadeLayer): Deleted.
+        (WebCore::Style::RuleSet::Builder::updateCascadeLayerOrder): Deleted.
+        (WebCore::Style::RuleSet::Builder::addMutatingRulesToResolver): Deleted.
+        (WebCore::Style::RuleSet::MediaQueryCollector::pushAndEvaluate): Deleted.
+        (WebCore::Style::RuleSet::MediaQueryCollector::pop): Deleted.
+        (WebCore::Style::RuleSet::MediaQueryCollector::didMutateResolver): Deleted.
+        (WebCore::Style::RuleSet::MediaQueryCollector::addRuleIfNeeded): Deleted.
+
+        MediaQueryCollector (an implementation detail of the Builder) moves too.
+
+        * style/RuleSet.h:
+        * style/RuleSetBuilder.cpp: Added.
+        (WebCore::Style::RuleSetBuilder::~RuleSetBuilder):
+        (WebCore::Style::RuleSetBuilder::addChildRules):
+        (WebCore::Style::RuleSetBuilder::addRulesFromSheet):
+        (WebCore::Style::RuleSetBuilder::addStyleRule):
+        (WebCore::Style::RuleSetBuilder::registerLayers):
+        (WebCore::Style::RuleSetBuilder::pushCascadeLayer):
+        (WebCore::Style::RuleSetBuilder::popCascadeLayer):
+        (WebCore::Style::RuleSetBuilder::updateCascadeLayerOrder):
+        (WebCore::Style::RuleSetBuilder::addMutatingRulesToResolver):
+        (WebCore::Style::RuleSetMediaQueryCollector::pushAndEvaluate):
+        (WebCore::Style::RuleSetMediaQueryCollector::pop):
+        (WebCore::Style::RuleSetMediaQueryCollector::didMutateResolver):
+        (WebCore::Style::RuleSetMediaQueryCollector::addRuleIfNeeded):
+        * style/RuleSetBuilder.h: Added.
+
 2021-10-03  Alan Bujtas  <[email protected]>
 
         [LFC][IFC] Do not take hanging whitespace sequence into account while finding expansion opportunities

Modified: trunk/Source/WebCore/Sources.txt (283487 => 283488)


--- trunk/Source/WebCore/Sources.txt	2021-10-04 05:37:08 UTC (rev 283487)
+++ trunk/Source/WebCore/Sources.txt	2021-10-04 06:37:45 UTC (rev 283488)
@@ -2480,6 +2480,7 @@
 style/RuleData.cpp
 style/RuleFeature.cpp
 style/RuleSet.cpp
+style/RuleSetBuilder.cpp
 style/StyleAdjuster.cpp
 style/StyleBuilder.cpp
 style/StyleBuilderState.cpp

Modified: trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj (283487 => 283488)


--- trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-10-04 05:37:08 UTC (rev 283487)
+++ trunk/Source/WebCore/WebCore.xcodeproj/project.pbxproj	2021-10-04 06:37:45 UTC (rev 283488)
@@ -5271,6 +5271,7 @@
 		E47C39321FE6E10500BBBC6B /* RenderTreeBuilderList.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C39281FE6E0DD00BBBC6B /* RenderTreeBuilderList.h */; };
 		E47C39331FE6E10800BBBC6B /* RenderTreeBuilderMultiColumn.h in Headers */ = {isa = PBXBuildFile; fileRef = E47C39271FE6E0DC00BBBC6B /* RenderTreeBuilderMultiColumn.h */; };
 		E47CEBC92706EF5200B8D8F5 /* InlineWalker.h in Headers */ = {isa = PBXBuildFile; fileRef = E47CEBC72706EF5100B8D8F5 /* InlineWalker.h */; };
+		E47CEBEA2709DFD100B8D8F5 /* RuleSetBuilder.h in Headers */ = {isa = PBXBuildFile; fileRef = E47CEBE82709DFD000B8D8F5 /* RuleSetBuilder.h */; };
 		E47CEBE12709916D00B8D8F5 /* InlineIteratorTextBox.h in Headers */ = {isa = PBXBuildFile; fileRef = E47CEBE02709916D00B8D8F5 /* InlineIteratorTextBox.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E47E276516036ED200EE2AFB /* ExtensionStyleSheets.h in Headers */ = {isa = PBXBuildFile; fileRef = E47E276416036ED200EE2AFB /* ExtensionStyleSheets.h */; settings = {ATTRIBUTES = (Private, ); }; };
 		E47FC8A325B84D72005495FC /* LoadSchedulingMode.h in Headers */ = {isa = PBXBuildFile; fileRef = E47FC8A125B84D71005495FC /* LoadSchedulingMode.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -16531,6 +16532,8 @@
 		E47C392B1FE6E0DF00BBBC6B /* RenderTreeBuilderList.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderTreeBuilderList.cpp; sourceTree = "<group>"; };
 		E47C392C1FE6E0DF00BBBC6B /* RenderTreeUpdater.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderTreeUpdater.h; sourceTree = "<group>"; };
 		E47CEBC72706EF5100B8D8F5 /* InlineWalker.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineWalker.h; sourceTree = "<group>"; };
+		E47CEBE82709DFD000B8D8F5 /* RuleSetBuilder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RuleSetBuilder.h; sourceTree = "<group>"; };
+		E47CEBEB2709DFDC00B8D8F5 /* RuleSetBuilder.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = RuleSetBuilder.cpp; sourceTree = "<group>"; };
 		E47CEBDE2709916400B8D8F5 /* InlineIteratorTextBox.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = InlineIteratorTextBox.cpp; sourceTree = "<group>"; };
 		E47CEBE02709916D00B8D8F5 /* InlineIteratorTextBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InlineIteratorTextBox.h; sourceTree = "<group>"; };
 		E47E276416036ED200EE2AFB /* ExtensionStyleSheets.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ExtensionStyleSheets.h; sourceTree = "<group>"; };
@@ -29403,6 +29406,8 @@
 				A79BAD9E161E7F3F00C2E652 /* RuleFeature.h */,
 				A79BAD9F161E7F3F00C2E652 /* RuleSet.cpp */,
 				A79BADA0161E7F3F00C2E652 /* RuleSet.h */,
+				E47CEBEB2709DFDC00B8D8F5 /* RuleSetBuilder.cpp */,
+				E47CEBE82709DFD000B8D8F5 /* RuleSetBuilder.h */,
 				7173DEBD2614DF040097DF32 /* Styleable.cpp */,
 				713922BC2518AB70005DB3C2 /* Styleable.h */,
 				E45BA6B22376227E004DFC07 /* StyleAdjuster.cpp */,
@@ -35001,6 +35006,7 @@
 				E4863CFE23842E9E00972158 /* RuleData.h in Headers */,
 				A79BADA2161E7F3F00C2E652 /* RuleFeature.h in Headers */,
 				A79BADA4161E7F3F00C2E652 /* RuleSet.h in Headers */,
+				E47CEBEA2709DFD100B8D8F5 /* RuleSetBuilder.h in Headers */,
 				51BA947123AC305300444846 /* RunJavaScriptParameters.h in Headers */,
 				2D76BB821945632400CFD29A /* RunLoopObserver.h in Headers */,
 				1A569D1F0D7E2B82007C3983 /* runtime_array.h in Headers */,

Modified: trunk/Source/WebCore/style/RuleSet.cpp (283487 => 283488)


--- trunk/Source/WebCore/style/RuleSet.cpp	2021-10-04 05:37:08 UTC (rev 283487)
+++ trunk/Source/WebCore/style/RuleSet.cpp	2021-10-04 06:37:45 UTC (rev 283488)
@@ -35,6 +35,7 @@
 #include "CSSSelectorList.h"
 #include "HTMLNames.h"
 #include "MediaQueryEvaluator.h"
+#include "RuleSetBuilder.h"
 #include "SecurityOrigin.h"
 #include "SelectorChecker.h"
 #include "SelectorFilter.h"
@@ -83,7 +84,7 @@
     return leftmostSelector->match() == CSSSelector::PseudoClass && leftmostSelector->pseudoClassType() == CSSSelector::PseudoClassHost;
 }
 
-void RuleSet::addRule(const StyleRule& rule, unsigned selectorIndex, unsigned selectorListIndex, unsigned cascadeLayerIdentifier, MediaQueryCollector* mediaQueryCollector)
+void RuleSet::addRule(const StyleRule& rule, unsigned selectorIndex, unsigned selectorListIndex, unsigned cascadeLayerIdentifier, RuleSetMediaQueryCollector* mediaQueryCollector)
 {
     RuleData ruleData(rule, selectorIndex, selectorListIndex, m_ruleCount++);
 
@@ -273,7 +274,7 @@
 
 void RuleSet::addRulesFromSheet(const StyleSheetContents& sheet, const MediaQueryEvaluator& evaluator)
 {
-    Builder builder { *this, MediaQueryCollector { evaluator } };
+    RuleSetBuilder builder { *this, RuleSetMediaQueryCollector { evaluator } };
     builder.addRulesFromSheet(sheet);
 
     if (m_autoShrinkToFitEnabled)
@@ -283,7 +284,7 @@
 void RuleSet::addRulesFromSheet(const StyleSheetContents& sheet, const MediaQuerySet* sheetQuery, const MediaQueryEvaluator& evaluator, Style::Resolver& resolver)
 {
     auto canUseDynamicMediaQueryResolution = [&] {
-        Builder builder { *this, MediaQueryCollector { evaluator, true }, nullptr, Builder::Mode::ResolverMutationScan };
+        RuleSetBuilder builder { *this, RuleSetMediaQueryCollector { evaluator, true }, nullptr, RuleSetBuilder::Mode::ResolverMutationScan };
         if (builder.mediaQueryCollector.pushAndEvaluate(sheetQuery))
             builder.addRulesFromSheet(sheet);
         builder.mediaQueryCollector.pop(sheetQuery);
@@ -290,7 +291,7 @@
         return !builder.mediaQueryCollector.didMutateResolverWithinDynamicMediaQuery;
     }();
 
-    Builder builder { *this, MediaQueryCollector { evaluator, canUseDynamicMediaQueryResolution }, &resolver };
+    RuleSetBuilder builder { *this, RuleSetMediaQueryCollector { evaluator, canUseDynamicMediaQueryResolution }, &resolver };
 
     if (builder.mediaQueryCollector.pushAndEvaluate(sheetQuery))
         builder.addRulesFromSheet(sheet);
@@ -310,227 +311,6 @@
         shrinkToFit();
 }
 
-void RuleSet::Builder::addChildRules(const Vector<RefPtr<StyleRuleBase>>& rules)
-{
-    for (auto& rule : rules) {
-        if (mode == Mode::ResolverMutationScan && mediaQueryCollector.didMutateResolverWithinDynamicMediaQuery)
-            break;
-
-        if (is<StyleRule>(*rule)) {
-            if (mode == Mode::Normal)
-                addStyleRule(downcast<StyleRule>(*rule));
-            continue;
-        }
-        if (is<StyleRulePage>(*rule)) {
-            if (mode == Mode::Normal)
-                ruleSet->addPageRule(downcast<StyleRulePage>(*rule));
-            continue;
-        }
-        if (is<StyleRuleMedia>(*rule)) {
-            auto& mediaRule = downcast<StyleRuleMedia>(*rule);
-            if (mediaQueryCollector.pushAndEvaluate(&mediaRule.mediaQueries()))
-                addChildRules(mediaRule.childRules());
-            mediaQueryCollector.pop(&mediaRule.mediaQueries());
-            continue;
-        }
-        if (is<StyleRuleLayer>(*rule)) {
-            auto& layerRule = downcast<StyleRuleLayer>(*rule);
-            if (layerRule.isStatement()) {
-                // Statement syntax just registers the layers.
-                registerLayers(layerRule.nameList());
-                continue;
-            }
-            // Block syntax.
-            pushCascadeLayer(layerRule.name());
-            addChildRules(layerRule.childRules());
-            popCascadeLayer(layerRule.name());
-            continue;
-        }
-        if (is<StyleRuleFontFace>(*rule) || is<StyleRuleFontPaletteValues>(*rule) || is<StyleRuleKeyframes>(*rule)) {
-            if (mode == Mode::ResolverMutationScan) {
-                mediaQueryCollector.didMutateResolver();
-                continue;
-            }
-            if (resolver)
-                collectedResolverMutatingRules.append({ *rule, currentCascadeLayerIdentifier });
-            continue;
-        }
-        if (is<StyleRuleSupports>(*rule) && downcast<StyleRuleSupports>(*rule).conditionIsSupported()) {
-            addChildRules(downcast<StyleRuleSupports>(*rule).childRules());
-            continue;
-        }
-    }
-}
-
-void RuleSet::Builder::addRulesFromSheet(const StyleSheetContents& sheet)
-{
-    for (auto& rule : sheet.layerRulesBeforeImportRules())
-        registerLayers(rule->nameList());
-
-    for (auto& rule : sheet.importRules()) {
-        if (!rule->styleSheet())
-            continue;
-        
-        if (mediaQueryCollector.pushAndEvaluate(rule->mediaQueries())) {
-            auto& cascadeLayerName = rule->cascadeLayerName();
-            if (cascadeLayerName)
-                pushCascadeLayer(*cascadeLayerName);
-
-            addRulesFromSheet(*rule->styleSheet());
-
-            if (cascadeLayerName)
-                popCascadeLayer(*cascadeLayerName);
-        }
-        mediaQueryCollector.pop(rule->mediaQueries());
-    }
-
-    addChildRules(sheet.childRules());
-}
-
-RuleSet::Builder::~Builder()
-{
-    if (mode == Mode::ResolverMutationScan)
-        return;
-
-    updateCascadeLayerOrder();
-    addMutatingRulesToResolver();
-}
-
-void RuleSet::Builder::addStyleRule(const StyleRule& rule)
-{
-    auto& selectorList = rule.selectorList();
-    if (selectorList.isEmpty())
-        return;
-    unsigned selectorListIndex = 0;
-    for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex))
-        ruleSet->addRule(rule, selectorIndex, selectorListIndex++, currentCascadeLayerIdentifier, &mediaQueryCollector);
-}
-
-void RuleSet::Builder::registerLayers(const Vector<CascadeLayerName>& names)
-{
-    for (auto& name : names) {
-        pushCascadeLayer(name);
-        popCascadeLayer(name);
-    }
-}
-
-void RuleSet::Builder::pushCascadeLayer(const CascadeLayerName& name)
-{
-    if (mode != Mode::Normal)
-        return;
-
-    if (cascadeLayerIdentifierMap.isEmpty() && !ruleSet->m_cascadeLayers.isEmpty()) {
-        // For incremental build, reconstruct the name->identifier map.
-        CascadeLayerIdentifier identifier = 0;
-        for (auto& layer : ruleSet->m_cascadeLayers)
-            cascadeLayerIdentifierMap.add(layer.resolvedName, ++identifier);
-    }
-
-    auto nameResolvingAnonymous = [&] {
-        if (name.isEmpty()) {
-            // Make unique name for an anonymous layer.
-            unsigned long long random = randomNumber() * std::numeric_limits<unsigned long long>::max();
-            return CascadeLayerName { "anon_"_s + String::number(random) };
-        }
-        return name;
-    };
-
-    // For hierarchical names we register the containing layers individually first.
-    for (auto& nameSegment : nameResolvingAnonymous()) {
-        resolvedCascadeLayerName.append(nameSegment);
-        currentCascadeLayerIdentifier = cascadeLayerIdentifierMap.ensure(resolvedCascadeLayerName, [&] {
-            // Previously unseen layer.
-            ruleSet->m_cascadeLayers.append({ resolvedCascadeLayerName, currentCascadeLayerIdentifier });
-            return ruleSet->m_cascadeLayers.size();
-        }).iterator->value;
-    }
-}
-
-void RuleSet::Builder::popCascadeLayer(const CascadeLayerName& name)
-{
-    if (mode != Mode::Normal)
-        return;
-
-    for (auto size = name.isEmpty() ? 1 : name.size(); size--;) {
-        resolvedCascadeLayerName.removeLast();
-        currentCascadeLayerIdentifier = ruleSet->cascadeLayerForIdentifier(currentCascadeLayerIdentifier).parentIdentifier;
-    }
-}
-
-void RuleSet::Builder::updateCascadeLayerOrder()
-{
-    if (cascadeLayerIdentifierMap.isEmpty())
-        return;
-
-    auto compare = [&](CascadeLayerIdentifier a, CascadeLayerIdentifier b) {
-        while (a && b) {
-            // Identifiers are in parse order which almost corresponds to the layer priority order.
-            // The only exception is when a sublayer gets added to a layer after adding other non-sublayers.
-            // To resolve this we need look for a shared ancestor layer.
-            auto aParent = ruleSet->cascadeLayerForIdentifier(a).parentIdentifier;
-            auto bParent = ruleSet->cascadeLayerForIdentifier(b).parentIdentifier;
-            if (aParent == bParent || aParent == b || bParent == a)
-                break;
-            if (aParent > bParent)
-                a = aParent;
-            else
-                b = bParent;
-        }
-        return a < b;
-    };
-
-    Vector<CascadeLayerIdentifier> orderVector;
-    auto layerCount = ruleSet->m_cascadeLayers.size();
-    orderVector.reserveInitialCapacity(layerCount);
-    for (CascadeLayerIdentifier identifier = 1; identifier <= layerCount; ++identifier)
-        orderVector.uncheckedAppend(identifier);
-
-    std::sort(orderVector.begin(), orderVector.end(), compare);
-
-    for (unsigned i = 0; i < orderVector.size(); ++i)
-        ruleSet->cascadeLayerForIdentifier(orderVector[i]).order = i + 1;
-}
-
-void RuleSet::Builder::addMutatingRulesToResolver()
-{
-    if (!resolver)
-        return;
-
-    auto compareLayers = [&](const ResolverMutatingRule& a, const ResolverMutatingRule& b) {
-        auto aOrder = ruleSet->cascadeLayerOrderForIdentifier(a.layerIdentifier);
-        auto bOrder = ruleSet->cascadeLayerOrderForIdentifier(b.layerIdentifier);
-        return aOrder < bOrder;
-    };
-
-    // The order may change so we need to reprocess resolver mutating rules from earlier stylesheets.
-    auto rulesToAdd = std::exchange(ruleSet->m_resolverMutatingRulesInLayers, { });
-    rulesToAdd.appendVector(WTFMove(collectedResolverMutatingRules));
-
-    if (!cascadeLayerIdentifierMap.isEmpty())
-        std::stable_sort(rulesToAdd.begin(), rulesToAdd.end(), compareLayers);
-
-    for (auto& collectedRule : rulesToAdd) {
-        if (collectedRule.layerIdentifier)
-            ruleSet->m_resolverMutatingRulesInLayers.append(collectedRule);
-
-        auto& rule = collectedRule.rule;
-        if (is<StyleRuleFontFace>(rule)) {
-            resolver->document().fontSelector().addFontFaceRule(downcast<StyleRuleFontFace>(rule.get()), false);
-            resolver->invalidateMatchedDeclarationsCache();
-            continue;
-        }
-        if (is<StyleRuleFontPaletteValues>(rule)) {
-            resolver->document().fontSelector().addFontPaletteValuesRule(downcast<StyleRuleFontPaletteValues>(rule.get()));
-            resolver->invalidateMatchedDeclarationsCache();
-            continue;
-        }
-        if (is<StyleRuleKeyframes>(rule)) {
-            resolver->addKeyframeStyle(downcast<StyleRuleKeyframes>(rule.get()));
-            continue;
-        }
-    }
-}
-
 template<typename Function>
 void RuleSet::traverseRuleDatas(Function&& function)
 {
@@ -670,67 +450,5 @@
     m_resolverMutatingRulesInLayers.shrinkToFit();
 }
 
-RuleSet::MediaQueryCollector::~MediaQueryCollector() = default;
-
-bool RuleSet::MediaQueryCollector::pushAndEvaluate(const MediaQuerySet* set)
-{
-    if (!set)
-        return true;
-
-    // Only evaluate static expressions that require style rebuild.
-    MediaQueryDynamicResults dynamicResults;
-    auto mode = collectDynamic ? MediaQueryEvaluator::Mode::AlwaysMatchDynamic : MediaQueryEvaluator::Mode::Normal;
-
-    bool result = evaluator.evaluate(*set, &dynamicResults, mode);
-
-    if (!dynamicResults.viewport.isEmpty())
-        hasViewportDependentMediaQueries = true;
-
-    if (!dynamicResults.isEmpty())
-        dynamicContextStack.append({ *set });
-
-    return result;
-}
-
-void RuleSet::MediaQueryCollector::pop(const MediaQuerySet* set)
-{
-    if (!set || dynamicContextStack.isEmpty() || set != &dynamicContextStack.last().set.get())
-        return;
-
-    if (!dynamicContextStack.last().affectedRulePositions.isEmpty() || !collectDynamic) {
-        DynamicMediaQueryRules rules;
-        for (auto& context : dynamicContextStack)
-            rules.mediaQuerySets.append(context.set.get());
-
-        if (collectDynamic) {
-            rules.affectedRulePositions.appendVector(dynamicContextStack.last().affectedRulePositions);
-            rules.ruleFeatures = WTFMove(dynamicContextStack.last().ruleFeatures);
-            rules.ruleFeatures.shrinkToFit();
-        } else
-            rules.requiresFullReset = true;
-
-        dynamicMediaQueryRules.append(WTFMove(rules));
-    }
-
-    dynamicContextStack.removeLast();
-}
-
-void RuleSet::MediaQueryCollector::didMutateResolver()
-{
-    if (dynamicContextStack.isEmpty())
-        return;
-    didMutateResolverWithinDynamicMediaQuery = true;
-}
-
-void RuleSet::MediaQueryCollector::addRuleIfNeeded(const RuleData& ruleData)
-{
-    if (dynamicContextStack.isEmpty())
-        return;
-
-    auto& context = dynamicContextStack.last();
-    context.affectedRulePositions.append(ruleData.position());
-    context.ruleFeatures.append({ ruleData });
-}
-
 } // namespace Style
 } // namespace WebCore

Modified: trunk/Source/WebCore/style/RuleSet.h (283487 => 283488)


--- trunk/Source/WebCore/style/RuleSet.h	2021-10-04 05:37:08 UTC (rev 283487)
+++ trunk/Source/WebCore/style/RuleSet.h	2021-10-04 06:37:45 UTC (rev 283488)
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 1999 Lars Knoll ([email protected])
- * Copyright (C) 2003-2019 Apple Inc. All rights reserved.
+ * Copyright (C) 2003-2021 Apple Inc. All rights reserved.
  *
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Library General Public
@@ -42,6 +42,7 @@
 
 class Resolver;
 class RuleSet;
+struct RuleSetMediaQueryCollector;
 
 using InvalidationRuleSetVector = Vector<RefPtr<const RuleSet>, 1>;
 
@@ -85,33 +86,10 @@
         }
     };
 
-    struct MediaQueryCollector {
-        ~MediaQueryCollector();
-
-        const MediaQueryEvaluator& evaluator;
-        const bool collectDynamic { false };
-
-        struct DynamicContext {
-            Ref<const MediaQuerySet> set;
-            Vector<size_t> affectedRulePositions { };
-            RuleFeatureVector ruleFeatures { };
-        };
-        Vector<DynamicContext> dynamicContextStack { };
-
-        Vector<DynamicMediaQueryRules> dynamicMediaQueryRules { };
-        bool didMutateResolverWithinDynamicMediaQuery { false };
-        bool hasViewportDependentMediaQueries { false };
-
-        bool pushAndEvaluate(const MediaQuerySet*);
-        void pop(const MediaQuerySet*);
-        void didMutateResolver();
-        void addRuleIfNeeded(const RuleData&);
-    };
-
     void addRulesFromSheet(const StyleSheetContents&, const MediaQueryEvaluator&);
     void addRulesFromSheet(const StyleSheetContents&, const MediaQuerySet* sheetQuery, const MediaQueryEvaluator&, Style::Resolver&);
 
-    void addRule(const StyleRule&, unsigned selectorIndex, unsigned selectorListIndex, unsigned cascadeLayerOrder = 0, MediaQueryCollector* = nullptr);
+    void addRule(const StyleRule&, unsigned selectorIndex, unsigned selectorListIndex, unsigned cascadeLayerOrder = 0, RuleSetMediaQueryCollector* = nullptr);
     void addPageRule(StyleRulePage&);
 
     void addToRuleSet(const AtomString& key, AtomRuleMap&, const RuleData&);
@@ -148,6 +126,8 @@
     unsigned cascadeLayerOrderFor(const RuleData&) const;
 
 private:
+    friend struct RuleSetBuilder;
+
     RuleSet();
 
     using CascadeLayerIdentifier = unsigned;
@@ -157,33 +137,6 @@
         CascadeLayerIdentifier layerIdentifier;
     };
 
-    struct Builder {
-        enum class Mode { Normal, ResolverMutationScan };
-
-        Ref<RuleSet> ruleSet;
-        MediaQueryCollector mediaQueryCollector;
-        Style::Resolver* resolver { nullptr };
-        Mode mode { Mode::Normal };
-        CascadeLayerName resolvedCascadeLayerName { };
-        HashMap<CascadeLayerName, CascadeLayerIdentifier> cascadeLayerIdentifierMap { };
-        CascadeLayerIdentifier currentCascadeLayerIdentifier { 0 };
-        Vector<ResolverMutatingRule> collectedResolverMutatingRules { };
-
-        void addRulesFromSheet(const StyleSheetContents&);
-
-        ~Builder();
-        
-    private:
-        void addChildRules(const Vector<RefPtr<StyleRuleBase>>&);
-        void addStyleRule(const StyleRule&);
-
-        void registerLayers(const Vector<CascadeLayerName>&);
-        void pushCascadeLayer(const CascadeLayerName&);
-        void popCascadeLayer(const CascadeLayerName&);
-        void updateCascadeLayerOrder();
-        void addMutatingRulesToResolver();
-    };
-
     struct CollectedMediaQueryChanges {
         bool requiredFullReset { false };
         Vector<size_t> changedQueryIndexes { };

Added: trunk/Source/WebCore/style/RuleSetBuilder.cpp (0 => 283488)


--- trunk/Source/WebCore/style/RuleSetBuilder.cpp	                        (rev 0)
+++ trunk/Source/WebCore/style/RuleSetBuilder.cpp	2021-10-04 06:37:45 UTC (rev 283488)
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 1999 Lars Knoll ([email protected])
+ *           (C) 2004-2005 Allan Sandfeld Jensen ([email protected])
+ * Copyright (C) 2006, 2007 Nicholas Shanks ([email protected])
+ * Copyright (C) 2005-2021 Apple Inc. All rights reserved.
+ * Copyright (C) 2007 Alexey Proskuryakov <[email protected]>
+ * Copyright (C) 2007, 2008 Eric Seidel <[email protected]>
+ * Copyright (C) 2008, 2009 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+ * Copyright (C) Research In Motion Limited 2011. All rights reserved.
+ * Copyright (C) 2012 Google Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ */
+
+#include "config.h"
+#include "RuleSetBuilder.h"
+
+namespace WebCore {
+namespace Style {
+
+RuleSetBuilder::~RuleSetBuilder()
+{
+    if (mode == Mode::ResolverMutationScan)
+        return;
+
+    updateCascadeLayerOrder();
+    addMutatingRulesToResolver();
+}
+
+void RuleSetBuilder::addChildRules(const Vector<RefPtr<StyleRuleBase>>& rules)
+{
+    for (auto& rule : rules) {
+        if (mode == Mode::ResolverMutationScan && mediaQueryCollector.didMutateResolverWithinDynamicMediaQuery)
+            break;
+
+        if (is<StyleRule>(*rule)) {
+            if (mode == Mode::Normal)
+                addStyleRule(downcast<StyleRule>(*rule));
+            continue;
+        }
+        if (is<StyleRulePage>(*rule)) {
+            if (mode == Mode::Normal)
+                ruleSet->addPageRule(downcast<StyleRulePage>(*rule));
+            continue;
+        }
+        if (is<StyleRuleMedia>(*rule)) {
+            auto& mediaRule = downcast<StyleRuleMedia>(*rule);
+            if (mediaQueryCollector.pushAndEvaluate(&mediaRule.mediaQueries()))
+                addChildRules(mediaRule.childRules());
+            mediaQueryCollector.pop(&mediaRule.mediaQueries());
+            continue;
+        }
+        if (is<StyleRuleLayer>(*rule)) {
+            auto& layerRule = downcast<StyleRuleLayer>(*rule);
+            if (layerRule.isStatement()) {
+                // Statement syntax just registers the layers.
+                registerLayers(layerRule.nameList());
+                continue;
+            }
+            // Block syntax.
+            pushCascadeLayer(layerRule.name());
+            addChildRules(layerRule.childRules());
+            popCascadeLayer(layerRule.name());
+            continue;
+        }
+        if (is<StyleRuleFontFace>(*rule) || is<StyleRuleFontPaletteValues>(*rule) || is<StyleRuleKeyframes>(*rule)) {
+            if (mode == Mode::ResolverMutationScan) {
+                mediaQueryCollector.didMutateResolver();
+                continue;
+            }
+            if (resolver)
+                collectedResolverMutatingRules.append({ *rule, currentCascadeLayerIdentifier });
+            continue;
+        }
+        if (is<StyleRuleSupports>(*rule) && downcast<StyleRuleSupports>(*rule).conditionIsSupported()) {
+            addChildRules(downcast<StyleRuleSupports>(*rule).childRules());
+            continue;
+        }
+    }
+}
+
+void RuleSetBuilder::addRulesFromSheet(const StyleSheetContents& sheet)
+{
+    for (auto& rule : sheet.layerRulesBeforeImportRules())
+        registerLayers(rule->nameList());
+
+    for (auto& rule : sheet.importRules()) {
+        if (!rule->styleSheet())
+            continue;
+
+        if (mediaQueryCollector.pushAndEvaluate(rule->mediaQueries())) {
+            auto& cascadeLayerName = rule->cascadeLayerName();
+            if (cascadeLayerName)
+                pushCascadeLayer(*cascadeLayerName);
+
+            addRulesFromSheet(*rule->styleSheet());
+
+            if (cascadeLayerName)
+                popCascadeLayer(*cascadeLayerName);
+        }
+        mediaQueryCollector.pop(rule->mediaQueries());
+    }
+
+    addChildRules(sheet.childRules());
+}
+
+void RuleSetBuilder::addStyleRule(const StyleRule& rule)
+{
+    auto& selectorList = rule.selectorList();
+    if (selectorList.isEmpty())
+        return;
+    unsigned selectorListIndex = 0;
+    for (size_t selectorIndex = 0; selectorIndex != notFound; selectorIndex = selectorList.indexOfNextSelectorAfter(selectorIndex))
+        ruleSet->addRule(rule, selectorIndex, selectorListIndex++, currentCascadeLayerIdentifier, &mediaQueryCollector);
+}
+
+void RuleSetBuilder::registerLayers(const Vector<CascadeLayerName>& names)
+{
+    for (auto& name : names) {
+        pushCascadeLayer(name);
+        popCascadeLayer(name);
+    }
+}
+
+void RuleSetBuilder::pushCascadeLayer(const CascadeLayerName& name)
+{
+    if (mode != Mode::Normal)
+        return;
+
+    if (cascadeLayerIdentifierMap.isEmpty() && !ruleSet->m_cascadeLayers.isEmpty()) {
+        // For incremental build, reconstruct the name->identifier map.
+        RuleSet::CascadeLayerIdentifier identifier = 0;
+        for (auto& layer : ruleSet->m_cascadeLayers)
+            cascadeLayerIdentifierMap.add(layer.resolvedName, ++identifier);
+    }
+
+    auto nameResolvingAnonymous = [&] {
+        if (name.isEmpty()) {
+            // Make unique name for an anonymous layer.
+            unsigned long long random = randomNumber() * std::numeric_limits<unsigned long long>::max();
+            return CascadeLayerName { "anon_"_s + String::number(random) };
+        }
+        return name;
+    };
+
+    // For hierarchical names we register the containing layers individually first.
+    for (auto& nameSegment : nameResolvingAnonymous()) {
+        resolvedCascadeLayerName.append(nameSegment);
+        currentCascadeLayerIdentifier = cascadeLayerIdentifierMap.ensure(resolvedCascadeLayerName, [&] {
+            // Previously unseen layer.
+            ruleSet->m_cascadeLayers.append({ resolvedCascadeLayerName, currentCascadeLayerIdentifier });
+            return ruleSet->m_cascadeLayers.size();
+        }).iterator->value;
+    }
+}
+
+void RuleSetBuilder::popCascadeLayer(const CascadeLayerName& name)
+{
+    if (mode != Mode::Normal)
+        return;
+
+    for (auto size = name.isEmpty() ? 1 : name.size(); size--;) {
+        resolvedCascadeLayerName.removeLast();
+        currentCascadeLayerIdentifier = ruleSet->cascadeLayerForIdentifier(currentCascadeLayerIdentifier).parentIdentifier;
+    }
+}
+
+void RuleSetBuilder::updateCascadeLayerOrder()
+{
+    if (cascadeLayerIdentifierMap.isEmpty())
+        return;
+
+    auto compare = [&](auto a, auto b) {
+        while (a && b) {
+            // Identifiers are in parse order which almost corresponds to the layer priority order.
+            // The only exception is when a sublayer gets added to a layer after adding other non-sublayers.
+            // To resolve this we need look for a shared ancestor layer.
+            auto aParent = ruleSet->cascadeLayerForIdentifier(a).parentIdentifier;
+            auto bParent = ruleSet->cascadeLayerForIdentifier(b).parentIdentifier;
+            if (aParent == bParent || aParent == b || bParent == a)
+                break;
+            if (aParent > bParent)
+                a = aParent;
+            else
+                b = bParent;
+        }
+        return a < b;
+    };
+
+    Vector<RuleSet::CascadeLayerIdentifier> orderVector;
+    auto layerCount = ruleSet->m_cascadeLayers.size();
+    orderVector.reserveInitialCapacity(layerCount);
+    for (RuleSet::CascadeLayerIdentifier identifier = 1; identifier <= layerCount; ++identifier)
+        orderVector.uncheckedAppend(identifier);
+
+    std::sort(orderVector.begin(), orderVector.end(), compare);
+
+    for (unsigned i = 0; i < orderVector.size(); ++i)
+        ruleSet->cascadeLayerForIdentifier(orderVector[i]).order = i + 1;
+}
+
+void RuleSetBuilder::addMutatingRulesToResolver()
+{
+    if (!resolver)
+        return;
+
+    auto compareLayers = [&](const auto& a, const auto& b) {
+        auto aOrder = ruleSet->cascadeLayerOrderForIdentifier(a.layerIdentifier);
+        auto bOrder = ruleSet->cascadeLayerOrderForIdentifier(b.layerIdentifier);
+        return aOrder < bOrder;
+    };
+
+    // The order may change so we need to reprocess resolver mutating rules from earlier stylesheets.
+    auto rulesToAdd = std::exchange(ruleSet->m_resolverMutatingRulesInLayers, { });
+    rulesToAdd.appendVector(WTFMove(collectedResolverMutatingRules));
+
+    if (!cascadeLayerIdentifierMap.isEmpty())
+        std::stable_sort(rulesToAdd.begin(), rulesToAdd.end(), compareLayers);
+
+    for (auto& collectedRule : rulesToAdd) {
+        if (collectedRule.layerIdentifier)
+            ruleSet->m_resolverMutatingRulesInLayers.append(collectedRule);
+
+        auto& rule = collectedRule.rule;
+        if (is<StyleRuleFontFace>(rule)) {
+            resolver->document().fontSelector().addFontFaceRule(downcast<StyleRuleFontFace>(rule.get()), false);
+            resolver->invalidateMatchedDeclarationsCache();
+            continue;
+        }
+        if (is<StyleRuleFontPaletteValues>(rule)) {
+            resolver->document().fontSelector().addFontPaletteValuesRule(downcast<StyleRuleFontPaletteValues>(rule.get()));
+            resolver->invalidateMatchedDeclarationsCache();
+            continue;
+        }
+        if (is<StyleRuleKeyframes>(rule)) {
+            resolver->addKeyframeStyle(downcast<StyleRuleKeyframes>(rule.get()));
+            continue;
+        }
+    }
+}
+
+RuleSetMediaQueryCollector::~RuleSetMediaQueryCollector() = default;
+
+bool RuleSetMediaQueryCollector::pushAndEvaluate(const MediaQuerySet* set)
+{
+    if (!set)
+        return true;
+
+    // Only evaluate static expressions that require style rebuild.
+    MediaQueryDynamicResults dynamicResults;
+    auto mode = collectDynamic ? MediaQueryEvaluator::Mode::AlwaysMatchDynamic : MediaQueryEvaluator::Mode::Normal;
+
+    bool result = evaluator.evaluate(*set, &dynamicResults, mode);
+
+    if (!dynamicResults.viewport.isEmpty())
+        hasViewportDependentMediaQueries = true;
+
+    if (!dynamicResults.isEmpty())
+        dynamicContextStack.append({ *set });
+
+    return result;
+}
+
+void RuleSetMediaQueryCollector::pop(const MediaQuerySet* set)
+{
+    if (!set || dynamicContextStack.isEmpty() || set != &dynamicContextStack.last().set.get())
+        return;
+
+    if (!dynamicContextStack.last().affectedRulePositions.isEmpty() || !collectDynamic) {
+        RuleSet::DynamicMediaQueryRules rules;
+        for (auto& context : dynamicContextStack)
+            rules.mediaQuerySets.append(context.set.get());
+
+        if (collectDynamic) {
+            rules.affectedRulePositions.appendVector(dynamicContextStack.last().affectedRulePositions);
+            rules.ruleFeatures = WTFMove(dynamicContextStack.last().ruleFeatures);
+            rules.ruleFeatures.shrinkToFit();
+        } else
+            rules.requiresFullReset = true;
+
+        dynamicMediaQueryRules.append(WTFMove(rules));
+    }
+
+    dynamicContextStack.removeLast();
+}
+
+void RuleSetMediaQueryCollector::didMutateResolver()
+{
+    if (dynamicContextStack.isEmpty())
+        return;
+    didMutateResolverWithinDynamicMediaQuery = true;
+}
+
+void RuleSetMediaQueryCollector::addRuleIfNeeded(const RuleData& ruleData)
+{
+    if (dynamicContextStack.isEmpty())
+        return;
+
+    auto& context = dynamicContextStack.last();
+    context.affectedRulePositions.append(ruleData.position());
+    context.ruleFeatures.append({ ruleData });
+}
+
+}
+}

Added: trunk/Source/WebCore/style/RuleSetBuilder.h (0 => 283488)


--- trunk/Source/WebCore/style/RuleSetBuilder.h	                        (rev 0)
+++ trunk/Source/WebCore/style/RuleSetBuilder.h	2021-10-04 06:37:45 UTC (rev 283488)
@@ -0,0 +1,80 @@
+/*
+ * Copyright (C) 1999 Lars Knoll ([email protected])
+ * Copyright (C) 2003-2021 Apple Inc. All rights reserved.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public License
+ * along with this library; see the file COPYING.LIB.  If not, write to
+ * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301, USA.
+ *
+ */
+
+#pragma once
+
+#include "RuleSet.h"
+
+namespace WebCore {
+namespace Style {
+
+struct RuleSetMediaQueryCollector {
+    ~RuleSetMediaQueryCollector();
+
+    const MediaQueryEvaluator& evaluator;
+    const bool collectDynamic { false };
+
+    struct DynamicContext {
+        Ref<const MediaQuerySet> set;
+        Vector<size_t> affectedRulePositions { };
+        RuleFeatureVector ruleFeatures { };
+    };
+    Vector<DynamicContext> dynamicContextStack { };
+
+    Vector<RuleSet::DynamicMediaQueryRules> dynamicMediaQueryRules { };
+    bool didMutateResolverWithinDynamicMediaQuery { false };
+    bool hasViewportDependentMediaQueries { false };
+
+    bool pushAndEvaluate(const MediaQuerySet*);
+    void pop(const MediaQuerySet*);
+    void didMutateResolver();
+    void addRuleIfNeeded(const RuleData&);
+};
+
+struct RuleSetBuilder {
+    enum class Mode { Normal, ResolverMutationScan };
+
+    Ref<RuleSet> ruleSet;
+    RuleSetMediaQueryCollector mediaQueryCollector;
+    Resolver* resolver { nullptr };
+    Mode mode { Mode::Normal };
+    CascadeLayerName resolvedCascadeLayerName { };
+    HashMap<CascadeLayerName, RuleSet::CascadeLayerIdentifier> cascadeLayerIdentifierMap { };
+    RuleSet::CascadeLayerIdentifier currentCascadeLayerIdentifier { 0 };
+    Vector<RuleSet::ResolverMutatingRule> collectedResolverMutatingRules { };
+
+    void addRulesFromSheet(const StyleSheetContents&);
+
+    ~RuleSetBuilder();
+
+private:
+    void addChildRules(const Vector<RefPtr<StyleRuleBase>>&);
+    void addStyleRule(const StyleRule&);
+
+    void registerLayers(const Vector<CascadeLayerName>&);
+    void pushCascadeLayer(const CascadeLayerName&);
+    void popCascadeLayer(const CascadeLayerName&);
+    void updateCascadeLayerOrder();
+    void addMutatingRulesToResolver();
+};
+
+}
+}
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to