Stack allocate StyleResolver state
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 10 Nov 2019 08:01:51 +0000 (08:01 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sun, 10 Nov 2019 08:01:51 +0000 (08:01 +0000)
https://bugs.webkit.org/show_bug.cgi?id=204053

Reviewed by Zalan Bujtas.

State is currently awkwardly a member that gets cleared. It should be stack allocated and
passed around where needed.

* animation/KeyframeEffect.cpp:
(WebCore::KeyframeEffect::updateBlendingKeyframes):
* css/DOMCSSRegisterCustomProperty.cpp:
(WebCore::DOMCSSRegisterCustomProperty::registerProperty):
* css/StyleResolver.cpp:
(WebCore::StyleResolver::builderContext):

Helper for initializing Style::Builder from resolver state.

(WebCore::StyleResolver::styleForElement):
(WebCore::StyleResolver::styleForKeyframe):
(WebCore::StyleResolver::keyframeStylesForAnimation):
(WebCore::StyleResolver::pseudoStyleForElement):
(WebCore::StyleResolver::styleForPage):
(WebCore::StyleResolver::defaultStyleForElement):
(WebCore::StyleResolver::pseudoStyleRulesForElement):
(WebCore::StyleResolver::applyMatchedProperties):
(WebCore::StyleResolver::State::clear): Deleted.

Nothing to clear, state is transient.

(WebCore::StyleResolver::setNewStateWithElement): Deleted.
(WebCore::StyleResolver::applyPropertyToStyle): Deleted.
(WebCore::StyleResolver::applyPropertyToCurrentStyle): Deleted.

Style::Builder can be used directly to apply properties instead of via these functions that require state setup.

(WebCore::StyleResolver::initializeFontStyle): Deleted.
* css/StyleResolver.h:
(WebCore::StyleResolver::inspectorCSSOMWrappers):
(WebCore::StyleResolver::style const): Deleted.
(WebCore::StyleResolver::parentStyle const): Deleted.
(WebCore::StyleResolver::rootElementStyle const): Deleted.
(WebCore::StyleResolver::element const): Deleted.
(WebCore::StyleResolver::state): Deleted.
(WebCore::StyleResolver::state const): Deleted.
* html/canvas/CanvasRenderingContext2D.cpp:
(WebCore::CanvasRenderingContext2D::setFont):

Use Style::Builder directly to apply properties.

* style/StyleBuilder.cpp:
(WebCore::Style::Builder::Builder):

Encapsulte immutable arguments into BuilderContext type.

(WebCore::Style::Builder::applyPropertyValue):
* style/StyleBuilder.h:
* style/StyleBuilderState.cpp:
(WebCore::Style::BuilderState::BuilderState):
(WebCore::Style::BuilderState::updateFontForZoomChange):
(WebCore::Style::BuilderState::updateFontForGenericFamilyChange):
* style/StyleBuilderState.h:
(WebCore::Style::BuilderState::parentStyle const):
(WebCore::Style::BuilderState::rootElementStyle const):
(WebCore::Style::BuilderState::document const):
(WebCore::Style::BuilderState::element const):
(WebCore::Style::BuilderState::parentFontDescription):

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

Source/WebCore/ChangeLog
Source/WebCore/animation/KeyframeEffect.cpp
Source/WebCore/css/DOMCSSRegisterCustomProperty.cpp
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleResolver.h
Source/WebCore/html/canvas/CanvasRenderingContext2D.cpp
Source/WebCore/style/PropertyCascade.h
Source/WebCore/style/StyleBuilder.cpp
Source/WebCore/style/StyleBuilder.h
Source/WebCore/style/StyleBuilderState.cpp
Source/WebCore/style/StyleBuilderState.h

index cfb51a0..681e161 100644 (file)
@@ -1,3 +1,72 @@
+2019-11-10  Antti Koivisto  <antti@apple.com>
+
+        Stack allocate StyleResolver state
+        https://bugs.webkit.org/show_bug.cgi?id=204053
+
+        Reviewed by Zalan Bujtas.
+
+        State is currently awkwardly a member that gets cleared. It should be stack allocated and
+        passed around where needed.
+
+        * animation/KeyframeEffect.cpp:
+        (WebCore::KeyframeEffect::updateBlendingKeyframes):
+        * css/DOMCSSRegisterCustomProperty.cpp:
+        (WebCore::DOMCSSRegisterCustomProperty::registerProperty):
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::builderContext):
+
+        Helper for initializing Style::Builder from resolver state.
+
+        (WebCore::StyleResolver::styleForElement):
+        (WebCore::StyleResolver::styleForKeyframe):
+        (WebCore::StyleResolver::keyframeStylesForAnimation):
+        (WebCore::StyleResolver::pseudoStyleForElement):
+        (WebCore::StyleResolver::styleForPage):
+        (WebCore::StyleResolver::defaultStyleForElement):
+        (WebCore::StyleResolver::pseudoStyleRulesForElement):
+        (WebCore::StyleResolver::applyMatchedProperties):
+        (WebCore::StyleResolver::State::clear): Deleted.
+
+        Nothing to clear, state is transient.
+
+        (WebCore::StyleResolver::setNewStateWithElement): Deleted.
+        (WebCore::StyleResolver::applyPropertyToStyle): Deleted.
+        (WebCore::StyleResolver::applyPropertyToCurrentStyle): Deleted.
+
+        Style::Builder can be used directly to apply properties instead of via these functions that require state setup.
+
+        (WebCore::StyleResolver::initializeFontStyle): Deleted.
+        * css/StyleResolver.h:
+        (WebCore::StyleResolver::inspectorCSSOMWrappers):
+        (WebCore::StyleResolver::style const): Deleted.
+        (WebCore::StyleResolver::parentStyle const): Deleted.
+        (WebCore::StyleResolver::rootElementStyle const): Deleted.
+        (WebCore::StyleResolver::element const): Deleted.
+        (WebCore::StyleResolver::state): Deleted.
+        (WebCore::StyleResolver::state const): Deleted.
+        * html/canvas/CanvasRenderingContext2D.cpp:
+        (WebCore::CanvasRenderingContext2D::setFont):
+
+        Use Style::Builder directly to apply properties.
+
+        * style/StyleBuilder.cpp:
+        (WebCore::Style::Builder::Builder):
+
+        Encapsulte immutable arguments into BuilderContext type.
+
+        (WebCore::Style::Builder::applyPropertyValue):
+        * style/StyleBuilder.h:
+        * style/StyleBuilderState.cpp:
+        (WebCore::Style::BuilderState::BuilderState):
+        (WebCore::Style::BuilderState::updateFontForZoomChange):
+        (WebCore::Style::BuilderState::updateFontForGenericFamilyChange):
+        * style/StyleBuilderState.h:
+        (WebCore::Style::BuilderState::parentStyle const):
+        (WebCore::Style::BuilderState::rootElementStyle const):
+        (WebCore::Style::BuilderState::document const):
+        (WebCore::Style::BuilderState::element const):
+        (WebCore::Style::BuilderState::parentFontDescription):
+
 2019-11-09  Antti Koivisto  <antti@apple.com>
 
         Move style adjustment code out of StyleResolver and into a class of its own
index 75776c5..fd89aed 100644 (file)
@@ -744,7 +744,6 @@ void KeyframeEffect::updateBlendingKeyframes(RenderStyle& elementStyle)
     StyleResolver& styleResolver = m_target->styleResolver();
 
     for (auto& keyframe : m_parsedKeyframes) {
-        styleResolver.setNewStateWithElement(*m_target);
         KeyframeValue keyframeValue(keyframe.computedOffset, nullptr);
 
         auto styleProperties = keyframe.style->immutableCopyIfNeeded();
@@ -752,7 +751,7 @@ void KeyframeEffect::updateBlendingKeyframes(RenderStyle& elementStyle)
             keyframeList.addProperty(styleProperties->propertyAt(i).id());
 
         auto keyframeRule = StyleRuleKeyframe::create(WTFMove(styleProperties));
-        keyframeValue.setStyle(styleResolver.styleForKeyframe(&elementStyle, keyframeRule.ptr(), keyframeValue));
+        keyframeValue.setStyle(styleResolver.styleForKeyframe(*m_target, &elementStyle, keyframeRule.ptr(), keyframeValue));
         keyframeList.insert(WTFMove(keyframeValue));
     }
 
index 2248c5b..42f80ab 100644 (file)
@@ -52,7 +52,7 @@ ExceptionOr<void> DOMCSSRegisterCustomProperty::registerProperty(Document& docum
 
         // We need to initialize this so that we can successfully parse computationally dependent values (like em units).
         // We don't actually need the values to be accurate, since they will be rejected later anyway
-        styleResolver.applyPropertyToStyle(CSSPropertyInvalid, nullptr, styleResolver.defaultStyleForElement());
+        auto style = styleResolver.defaultStyleForElement(nullptr);
 
         HashSet<CSSPropertyID> dependencies;
         CSSPropertyParser::collectParsedCustomPropertyValueDependencies(descriptor.syntax, false, dependencies, tokenizer.tokenRange(), strictCSSParserContext());
@@ -60,8 +60,12 @@ ExceptionOr<void> DOMCSSRegisterCustomProperty::registerProperty(Document& docum
         if (!dependencies.isEmpty())
             return Exception { SyntaxError, "The given initial value must be computationally independent." };
 
+
         MatchResult matchResult;
-        Style::Builder dummyBuilder(styleResolver, matchResult, { });
+
+        auto parentStyle = RenderStyle::clone(*style);
+        Style::Builder dummyBuilder(*style, { document, parentStyle }, matchResult, { });
+
         initialValue = CSSPropertyParser::parseTypedCustomPropertyValue(descriptor.name, descriptor.syntax, tokenizer.tokenRange(), dummyBuilder.state(), strictCSSParserContext());
 
         if (!initialValue || !initialValue->isResolved())
index f413f72..5edbfec 100644 (file)
@@ -84,14 +84,6 @@ namespace WebCore {
 
 using namespace HTMLNames;
 
-inline void StyleResolver::State::clear()
-{
-    m_element = nullptr;
-    m_parentStyle = nullptr;
-    m_ownedParentStyle = nullptr;
-    m_userAgentAppearanceStyle = nullptr;
-}
-
 StyleResolver::StyleResolver(Document& document)
     : m_ruleSets(*this)
     , m_document(document)
@@ -173,10 +165,9 @@ StyleResolver::~StyleResolver()
 #endif
 }
 
-StyleResolver::State::State(const Element& element, const RenderStyle* parentStyle, const RenderStyle* documentElementStyle, const SelectorFilter* selectorFilter)
+StyleResolver::State::State(const Element& element, const RenderStyle* parentStyle, const RenderStyle* documentElementStyle)
     : m_element(&element)
     , m_parentStyle(parentStyle)
-    , m_selectorFilter(selectorFilter)
 {
     bool resetStyleInheritance = hasShadowRootParent(element) && downcast<ShadowRoot>(element.parentNode())->resetStyleInheritance();
     if (resetStyleInheritance)
@@ -207,24 +198,27 @@ static inline bool isAtShadowBoundary(const Element& element)
     return parentNode && parentNode->isShadowRoot();
 }
 
-void StyleResolver::setNewStateWithElement(const Element& element)
+Style::BuilderContext StyleResolver::builderContext(const State& state)
 {
-    // Apply the declaration to the style. This is a simplified version of the logic in styleForElement.
-    m_state = State(element, nullptr);
+    return {
+        m_document,
+        *state.parentStyle(),
+        state.rootElementStyle(),
+        state.element()
+    };
 }
 
 ElementStyle StyleResolver::styleForElement(const Element& element, const RenderStyle* parentStyle, const RenderStyle* parentBoxStyle, RuleMatchingBehavior matchingBehavior, const SelectorFilter* selectorFilter)
 {
     RELEASE_ASSERT(!m_isDeleted);
 
-    m_state = State(element, parentStyle, m_overrideDocumentElementStyle, selectorFilter);
-    State& state = m_state;
+    auto state = State(element, parentStyle, m_overrideDocumentElementStyle);
 
     if (state.parentStyle()) {
         state.setStyle(RenderStyle::createPtr());
         state.style()->inheritFrom(*state.parentStyle());
     } else {
-        state.setStyle(defaultStyleForElement());
+        state.setStyle(defaultStyleForElement(&element));
         state.setParentStyle(RenderStyle::clonePtr(*state.style()));
     }
 
@@ -243,7 +237,7 @@ ElementStyle StyleResolver::styleForElement(const Element& element, const Render
 
     CSSDefaultStyleSheets::ensureDefaultStyleSheetsForElement(element);
 
-    ElementRuleCollector collector(element, m_ruleSets, m_state.selectorFilter());
+    ElementRuleCollector collector(element, m_ruleSets, selectorFilter);
     collector.setMedium(&m_mediaQueryEvaluator);
 
     if (matchingBehavior == RuleMatchingBehavior::MatchOnlyUserAgentRules)
@@ -260,7 +254,7 @@ ElementStyle StyleResolver::styleForElement(const Element& element, const Render
 
     auto elementStyleRelations = Style::commitRelationsToRenderStyle(style, element, collector.styleRelations());
 
-    applyMatchedProperties(collector.matchResult(), element);
+    applyMatchedProperties(state, collector.matchResult());
 
     Style::Adjuster adjuster(document(), *state.parentStyle(), parentBoxStyle, &element);
     adjuster.adjust(*state.style(), state.userAgentAppearanceStyle());
@@ -268,27 +262,22 @@ ElementStyle StyleResolver::styleForElement(const Element& element, const Render
     if (state.style()->hasViewportUnits())
         document().setHasStyleWithViewportUnits();
 
-    state.clear(); // Clear out for the next resolve.
-
     return { state.takeStyle(), WTFMove(elementStyleRelations) };
 }
 
-std::unique_ptr<RenderStyle> StyleResolver::styleForKeyframe(const RenderStyle* elementStyle, const StyleRuleKeyframe* keyframe, KeyframeValue& keyframeValue)
+std::unique_ptr<RenderStyle> StyleResolver::styleForKeyframe(const Element& element, const RenderStyle* elementStyle, const StyleRuleKeyframe* keyframe, KeyframeValue& keyframeValue)
 {
     RELEASE_ASSERT(!m_isDeleted);
 
     MatchResult result;
     result.authorDeclarations.append({ &keyframe->properties() });
 
-    ASSERT(!m_state.style());
-
-    State& state = m_state;
+    auto state = State(element, nullptr);
 
-    // Create the style
     state.setStyle(RenderStyle::clonePtr(*elementStyle));
     state.setParentStyle(RenderStyle::clonePtr(*elementStyle));
 
-    Style::Builder builder(*this, result, { Style::CascadeLevel::Author });
+    Style::Builder builder(*state.style(), builderContext(state), result, { Style::CascadeLevel::Author });
     builder.applyAllProperties();
 
     Style::Adjuster adjuster(document(), *state.parentStyle(), nullptr, nullptr);
@@ -371,12 +360,10 @@ void StyleResolver::keyframeStylesForAnimation(const Element& element, const Ren
 
     // Construct and populate the style for each keyframe.
     for (auto& keyframe : *keyframes) {
-        setNewStateWithElement(element);
-
         // Add this keyframe style to all the indicated key times
         for (auto key : keyframe->keys()) {
             KeyframeValue keyframeValue(0, nullptr);
-            keyframeValue.setStyle(styleForKeyframe(elementStyle, keyframe.ptr(), keyframeValue));
+            keyframeValue.setStyle(styleForKeyframe(element, elementStyle, keyframe.ptr(), keyframeValue));
             keyframeValue.setKey(key);
             if (auto timingFunctionCSSValue = keyframe->properties().getPropertyCSSValue(CSSPropertyAnimationTimingFunction))
                 keyframeValue.setTimingFunction(TimingFunction::createFromCSSValue(*timingFunctionCSSValue.get()));
@@ -393,7 +380,7 @@ void StyleResolver::keyframeStylesForAnimation(const Element& element, const Ren
             zeroPercentKeyframe->setKey(0);
         }
         KeyframeValue keyframeValue(0, nullptr);
-        keyframeValue.setStyle(styleForKeyframe(elementStyle, zeroPercentKeyframe, keyframeValue));
+        keyframeValue.setStyle(styleForKeyframe(element, elementStyle, zeroPercentKeyframe, keyframeValue));
         list.insert(WTFMove(keyframeValue));
     }
 
@@ -405,30 +392,24 @@ void StyleResolver::keyframeStylesForAnimation(const Element& element, const Ren
             hundredPercentKeyframe->setKey(1);
         }
         KeyframeValue keyframeValue(1, nullptr);
-        keyframeValue.setStyle(styleForKeyframe(elementStyle, hundredPercentKeyframe, keyframeValue));
+        keyframeValue.setStyle(styleForKeyframe(element, elementStyle, hundredPercentKeyframe, keyframeValue));
         list.insert(WTFMove(keyframeValue));
     }
 }
 
 std::unique_ptr<RenderStyle> StyleResolver::pseudoStyleForElement(const Element& element, const PseudoStyleRequest& pseudoStyleRequest, const RenderStyle& parentStyle, const RenderStyle* parentBoxStyle, const SelectorFilter* selectorFilter)
 {
-    m_state = State(element, &parentStyle, m_overrideDocumentElementStyle, selectorFilter);
+    auto state = State(element, &parentStyle, m_overrideDocumentElementStyle);
 
-    State& state = m_state;
-
-    if (m_state.parentStyle()) {
+    if (state.parentStyle()) {
         state.setStyle(RenderStyle::createPtr());
-        state.style()->inheritFrom(*m_state.parentStyle());
+        state.style()->inheritFrom(*state.parentStyle());
     } else {
-        state.setStyle(defaultStyleForElement());
+        state.setStyle(defaultStyleForElement(&element));
         state.setParentStyle(RenderStyle::clonePtr(*state.style()));
     }
 
-    // Since we don't use pseudo-elements in any of our quirk/print user agent rules, don't waste time walking
-    // those rules.
-
-    // Check UA, user and author rules.
-    ElementRuleCollector collector(element, m_ruleSets, m_state.selectorFilter());
+    ElementRuleCollector collector(element, m_ruleSets, selectorFilter);
     collector.setPseudoStyleRequest(pseudoStyleRequest);
     collector.setMedium(&m_mediaQueryEvaluator);
     collector.matchUARules();
@@ -445,7 +426,7 @@ std::unique_ptr<RenderStyle> StyleResolver::pseudoStyleForElement(const Element&
 
     state.style()->setStyleType(pseudoStyleRequest.pseudoId);
 
-    applyMatchedProperties(collector.matchResult(), element);
+    applyMatchedProperties(state, collector.matchResult());
 
     Style::Adjuster adjuster(document(), *state.parentStyle(), parentBoxStyle, nullptr);
     adjuster.adjust(*state.style(), state.userAgentAppearanceStyle());
@@ -453,7 +434,6 @@ std::unique_ptr<RenderStyle> StyleResolver::pseudoStyleForElement(const Element&
     if (state.style()->hasViewportUnits())
         document().setHasStyleWithViewportUnits();
 
-    // Now return the style.
     return state.takeStyle();
 }
 
@@ -465,30 +445,42 @@ std::unique_ptr<RenderStyle> StyleResolver::styleForPage(int pageIndex)
     if (!documentElement)
         return RenderStyle::createPtr();
 
-    m_state = State(*documentElement, m_document.renderStyle());
+    auto state = State(*documentElement, m_document.renderStyle());
 
-    m_state.setStyle(RenderStyle::createPtr());
-    m_state.style()->inheritFrom(*m_state.rootElementStyle());
+    state.setStyle(RenderStyle::createPtr());
+    state.style()->inheritFrom(*state.rootElementStyle());
 
-    PageRuleCollector collector(m_state, m_ruleSets);
+    PageRuleCollector collector(state, m_ruleSets);
     collector.matchAllPageRules(pageIndex);
 
     auto& result = collector.matchResult();
 
-    Style::Builder builder(*this, result, { Style::CascadeLevel::Author });
+    Style::Builder builder(*state.style(), builderContext(state), result, { Style::CascadeLevel::Author });
     builder.applyAllProperties();
 
     // Now return the style.
-    return m_state.takeStyle();
+    return state.takeStyle();
 }
 
-std::unique_ptr<RenderStyle> StyleResolver::defaultStyleForElement()
+std::unique_ptr<RenderStyle> StyleResolver::defaultStyleForElement(const Element* element)
 {
-    m_state.setStyle(RenderStyle::createPtr());
-    // Make sure our fonts are initialized if we don't inherit them from our parent style.
-    initializeFontStyle();
-    m_state.style()->fontCascade().update(&document().fontSelector());
-    return m_state.takeStyle();
+    auto style = RenderStyle::createPtr();
+
+    FontCascadeDescription fontDescription;
+    fontDescription.setRenderingMode(settings().fontRenderingMode());
+    fontDescription.setOneFamily(standardFamily);
+    fontDescription.setKeywordSizeFromIdentifier(CSSValueMedium);
+
+    auto size = Style::fontSizeForKeyword(CSSValueMedium, false, document());
+    fontDescription.setSpecifiedSize(size);
+    fontDescription.setComputedSize(Style::computedFontSizeFromSpecifiedSize(size, fontDescription.isAbsoluteSize(), is<SVGElement>(element), style.get(), document()));
+
+    fontDescription.setShouldAllowUserInstalledFonts(settings().shouldAllowUserInstalledFonts() ? AllowUserInstalledFonts::Yes : AllowUserInstalledFonts::No);
+    style->setFontDescription(WTFMove(fontDescription));
+
+    style->fontCascade().update(&document().fontSelector());
+
+    return style;
 }
 
 Vector<RefPtr<StyleRule>> StyleResolver::styleRulesForElement(const Element* element, unsigned rulesToInclude)
@@ -501,9 +493,9 @@ Vector<RefPtr<StyleRule>> StyleResolver::pseudoStyleRulesForElement(const Elemen
     if (!element)
         return { };
 
-    m_state = State(*element, nullptr);
+    auto state = State(*element, nullptr);
 
-    ElementRuleCollector collector(*element, m_ruleSets, m_state.selectorFilter());
+    ElementRuleCollector collector(*element, m_ruleSets, nullptr);
     collector.setMode(SelectorChecker::Mode::CollectingRules);
     collector.setPseudoStyleRequest(PseudoStyleRequest(pseudoId));
     collector.setMedium(&m_mediaQueryEvaluator);
@@ -546,14 +538,14 @@ void StyleResolver::clearCachedDeclarationsAffectedByViewportUnits()
     m_matchedDeclarationsCache.clearEntriesAffectedByViewportUnits();
 }
 
-void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, const Element& element, UseMatchedDeclarationsCache useMatchedDeclarationsCache)
+void StyleResolver::applyMatchedProperties(State& state, const MatchResult& matchResult, UseMatchedDeclarationsCache useMatchedDeclarationsCache)
 {
-    State& state = m_state;
     unsigned cacheHash = useMatchedDeclarationsCache == UseMatchedDeclarationsCache::Yes ? Style::MatchedDeclarationsCache::computeHash(matchResult) : 0;
     auto includedProperties = Style::PropertyCascade::IncludedProperties::All;
 
     auto& style = *state.style();
     auto& parentStyle = *state.parentStyle();
+    auto& element = *state.element();
 
     auto* cacheEntry = m_matchedDeclarationsCache.find(cacheHash, matchResult);
     if (cacheEntry && Style::MatchedDeclarationsCache::isCacheable(element, style, parentStyle)) {
@@ -579,24 +571,24 @@ void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, const
         // If so, we cache the border and background styles so that RenderTheme::adjustStyle()
         // can look at them later to figure out if this is a styled form control or not.
         auto userAgentStyle = RenderStyle::clonePtr(style);
-        Style::Builder builder(*userAgentStyle, *this, matchResult, { Style::CascadeLevel::UserAgent });
+        Style::Builder builder(*userAgentStyle, builderContext(state), matchResult, { Style::CascadeLevel::UserAgent });
         builder.applyAllProperties();
 
         state.setUserAgentAppearanceStyle(WTFMove(userAgentStyle));
     }
 
-    Style::Builder builder(*this, matchResult, Style::allCascadeLevels(), includedProperties);
+    Style::Builder builder(*state.style(), builderContext(state), matchResult, Style::allCascadeLevels(), includedProperties);
 
     // High priority properties may affect resolution of other properties (they are mostly font related).
     builder.applyHighPriorityProperties();
 
     // If the effective zoom value changes, we can't use the matched properties cache. Start over.
     if (cacheEntry && cacheEntry->renderStyle->effectiveZoom() != style.effectiveZoom())
-        return applyMatchedProperties(matchResult, element, UseMatchedDeclarationsCache::No);
+        return applyMatchedProperties(state, matchResult, UseMatchedDeclarationsCache::No);
 
     // If the font changed, we can't use the matched properties cache. Start over.
     if (cacheEntry && cacheEntry->renderStyle->fontDescription() != style.fontDescription())
-        return applyMatchedProperties(matchResult, element, UseMatchedDeclarationsCache::No);
+        return applyMatchedProperties(state, matchResult, UseMatchedDeclarationsCache::No);
 
     builder.applyLowPriorityProperties();
 
@@ -610,39 +602,6 @@ void StyleResolver::applyMatchedProperties(const MatchResult& matchResult, const
         m_matchedDeclarationsCache.add(style, parentStyle, cacheHash, matchResult);
 }
 
-void StyleResolver::applyPropertyToStyle(CSSPropertyID id, CSSValue* value, std::unique_ptr<RenderStyle> style)
-{
-    m_state = State();
-    m_state.setParentStyle(RenderStyle::clonePtr(*style));
-    m_state.setStyle(WTFMove(style));
-    applyPropertyToCurrentStyle(id, value);
-}
-
-void StyleResolver::applyPropertyToCurrentStyle(CSSPropertyID id, CSSValue* value)
-{
-    if (!value)
-        return;
-
-    MatchResult matchResult;
-    Style::Builder builder(*this, matchResult, { });
-    builder.applyPropertyValue(id, *value);
-}
-
-void StyleResolver::initializeFontStyle()
-{
-    FontCascadeDescription fontDescription;
-    fontDescription.setRenderingMode(settings().fontRenderingMode());
-    fontDescription.setOneFamily(standardFamily);
-    fontDescription.setKeywordSizeFromIdentifier(CSSValueMedium);
-
-    auto size = Style::fontSizeForKeyword(CSSValueMedium, false, document());
-    fontDescription.setSpecifiedSize(size);
-    fontDescription.setComputedSize(Style::computedFontSizeFromSpecifiedSize(size, fontDescription.isAbsoluteSize(), is<SVGElement>(m_state.element()), m_state.style(), document()));
-
-    fontDescription.setShouldAllowUserInstalledFonts(settings().shouldAllowUserInstalledFonts() ? AllowUserInstalledFonts::Yes : AllowUserInstalledFonts::No);
-    style()->setFontDescription(WTFMove(fontDescription));
-}
-
 void StyleResolver::addViewportDependentMediaQueryResult(const MediaQueryExpression& expression, bool result)
 {
     m_viewportDependentMediaQueryResults.append(MediaQueryResult { expression, result });
index 93e5c43..0e28240 100644 (file)
@@ -29,6 +29,7 @@
 #include "MediaQueryEvaluator.h"
 #include "RenderStyle.h"
 #include "RuleSet.h"
+#include "StyleBuilderState.h"
 #include <memory>
 #include <wtf/HashMap.h>
 #include <wtf/RefPtr.h>
@@ -112,12 +113,8 @@ public:
     std::unique_ptr<RenderStyle> pseudoStyleForElement(const Element&, const PseudoStyleRequest&, const RenderStyle& parentStyle, const RenderStyle* parentBoxStyle = nullptr, const SelectorFilter* = nullptr);
 
     std::unique_ptr<RenderStyle> styleForPage(int pageIndex);
-    std::unique_ptr<RenderStyle> defaultStyleForElement();
+    std::unique_ptr<RenderStyle> defaultStyleForElement(const Element*);
 
-    RenderStyle* style() const { return m_state.style(); }
-    const RenderStyle* parentStyle() const { return m_state.parentStyle(); }
-    const RenderStyle* rootElementStyle() const { return m_state.rootElementStyle(); }
-    const Element* element() const { return m_state.element(); }
     Document& document() { return m_document; }
     const Document& document() const { return m_document; }
     const Settings& settings() const { return m_document.settings(); }
@@ -134,8 +131,7 @@ public:
 
     void addCurrentSVGFontFaceRules();
 
-    void setNewStateWithElement(const Element&);
-    std::unique_ptr<RenderStyle> styleForKeyframe(const RenderStyle*, const StyleRuleKeyframe*, KeyframeValue&);
+    std::unique_ptr<RenderStyle> styleForKeyframe(const Element&, const RenderStyle*, const StyleRuleKeyframe*, KeyframeValue&);
     bool isAnimationNameValid(const String&);
 
     // These methods will give back the set of rules that matched for a given element (or a pseudo-element).
@@ -149,11 +145,6 @@ public:
     Vector<RefPtr<StyleRule>> styleRulesForElement(const Element*, unsigned rulesToInclude = AllButEmptyCSSRules);
     Vector<RefPtr<StyleRule>> pseudoStyleRulesForElement(const Element*, PseudoId, unsigned rulesToInclude = AllButEmptyCSSRules);
 
-    void applyPropertyToStyle(CSSPropertyID, CSSValue*, std::unique_ptr<RenderStyle>);
-    void applyPropertyToCurrentStyle(CSSPropertyID, CSSValue*);
-
-    void initializeFontStyle();
-
     bool hasSelectorForId(const AtomString&) const;
     bool hasSelectorForAttribute(const Element&, const AtomString&) const;
 
@@ -181,24 +172,17 @@ public:
     void invalidateMatchedDeclarationsCache();
     void clearCachedDeclarationsAffectedByViewportUnits();
 
-private:
-    enum class UseMatchedDeclarationsCache { Yes, No };
-    void applyMatchedProperties(const MatchResult&, const Element&, UseMatchedDeclarationsCache = UseMatchedDeclarationsCache::Yes);
-
-    DocumentRuleSets m_ruleSets;
+    InspectorCSSOMWrappers& inspectorCSSOMWrappers() { return m_inspectorCSSOMWrappers; }
 
-    typedef HashMap<AtomStringImpl*, RefPtr<StyleRuleKeyframes>> KeyframesRuleMap;
-    KeyframesRuleMap m_keyframesRuleMap;
+private:
+    friend class PageRuleCollector;
 
-public:
     class State {
     public:
         State() { }
-        State(const Element&, const RenderStyle* parentStyle, const RenderStyle* documentElementStyle = nullptr, const SelectorFilter* = nullptr);
+        State(const Element&, const RenderStyle* parentStyle, const RenderStyle* documentElementStyle = nullptr);
 
     public:
-        void clear();
-
         const Element* element() const { return m_element; }
 
         void setStyle(std::unique_ptr<RenderStyle>);
@@ -212,27 +196,25 @@ public:
         const RenderStyle* userAgentAppearanceStyle() const { return m_userAgentAppearanceStyle.get(); }
         void setUserAgentAppearanceStyle(std::unique_ptr<RenderStyle> style) { m_userAgentAppearanceStyle = WTFMove(style); }
 
-        const SelectorFilter* selectorFilter() const { return m_selectorFilter; }
-        
     private:
         const Element* m_element { nullptr };
         std::unique_ptr<RenderStyle> m_style;
         const RenderStyle* m_parentStyle { nullptr };
-        std::unique_ptr<RenderStyle> m_ownedParentStyle;
+        std::unique_ptr<const RenderStyle> m_ownedParentStyle;
         const RenderStyle* m_rootElementStyle { nullptr };
 
-        const SelectorFilter* m_selectorFilter { nullptr };
-
         std::unique_ptr<RenderStyle> m_userAgentAppearanceStyle;
     };
 
-    State& state() { return m_state; }
-    const State& state() const { return m_state; }
+    Style::BuilderContext builderContext(const State&);
 
-    InspectorCSSOMWrappers& inspectorCSSOMWrappers() { return m_inspectorCSSOMWrappers; }
+    enum class UseMatchedDeclarationsCache { Yes, No };
+    void applyMatchedProperties(State&, const MatchResult&, UseMatchedDeclarationsCache = UseMatchedDeclarationsCache::Yes);
 
-private:
-    void cacheBorderAndBackground();
+    DocumentRuleSets m_ruleSets;
+
+    typedef HashMap<AtomStringImpl*, RefPtr<StyleRuleKeyframes>> KeyframesRuleMap;
+    KeyframesRuleMap m_keyframesRuleMap;
 
     MediaQueryEvaluator m_mediaQueryEvaluator;
     std::unique_ptr<RenderStyle> m_rootDefaultStyle;
@@ -251,8 +233,6 @@ private:
 
     InspectorCSSOMWrappers m_inspectorCSSOMWrappers;
 
-    State m_state;
-
     Style::MatchedDeclarationsCache m_matchedDeclarationsCache;
 
     bool m_matchAuthorAndUserStyles { true };
index adc0361..6244741 100644 (file)
@@ -43,8 +43,8 @@
 #include "RenderTheme.h"
 #include "ResourceLoadObserver.h"
 #include "RuntimeEnabledFeatures.h"
+#include "StyleBuilder.h"
 #include "StyleProperties.h"
-#include "StyleResolver.h"
 #include "TextMetrics.h"
 #include "TextRun.h"
 #include <wtf/CheckedArithmetic.h>
@@ -171,15 +171,19 @@ void CanvasRenderingContext2D::setFont(const String& newFont)
     newStyle->fontCascade().update(&document.fontSelector());
 
     // Now map the font property longhands into the style.
-    StyleResolver& styleResolver = canvas().styleResolver();
-    styleResolver.applyPropertyToStyle(CSSPropertyFontFamily, parsedStyle->getPropertyCSSValue(CSSPropertyFontFamily).get(), WTFMove(newStyle));
-    styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontStyle, parsedStyle->getPropertyCSSValue(CSSPropertyFontStyle).get());
-    styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontVariantCaps, parsedStyle->getPropertyCSSValue(CSSPropertyFontVariantCaps).get());
-    styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontWeight, parsedStyle->getPropertyCSSValue(CSSPropertyFontWeight).get());
-    styleResolver.applyPropertyToCurrentStyle(CSSPropertyFontSize, parsedStyle->getPropertyCSSValue(CSSPropertyFontSize).get());
-    styleResolver.applyPropertyToCurrentStyle(CSSPropertyLineHeight, parsedStyle->getPropertyCSSValue(CSSPropertyLineHeight).get());
-
-    modifiableState().font.initialize(document.fontSelector(), *styleResolver.style());
+
+    MatchResult matchResult;
+    auto parentStyle = RenderStyle::clone(*newStyle);
+    WebCore::Style::Builder styleBuilder(*newStyle, { document, parentStyle }, matchResult, { });
+
+    styleBuilder.applyPropertyValue(CSSPropertyFontFamily, parsedStyle->getPropertyCSSValue(CSSPropertyFontFamily).get());
+    styleBuilder.applyPropertyValue(CSSPropertyFontStyle, parsedStyle->getPropertyCSSValue(CSSPropertyFontStyle).get());
+    styleBuilder.applyPropertyValue(CSSPropertyFontVariantCaps, parsedStyle->getPropertyCSSValue(CSSPropertyFontVariantCaps).get());
+    styleBuilder.applyPropertyValue(CSSPropertyFontWeight, parsedStyle->getPropertyCSSValue(CSSPropertyFontWeight).get());
+    styleBuilder.applyPropertyValue(CSSPropertyFontSize, parsedStyle->getPropertyCSSValue(CSSPropertyFontSize).get());
+    styleBuilder.applyPropertyValue(CSSPropertyLineHeight, parsedStyle->getPropertyCSSValue(CSSPropertyLineHeight).get());
+
+    modifiableState().font.initialize(document.fontSelector(), *newStyle);
 }
 
 static CanvasTextAlign toCanvasTextAlign(TextAlign textAlign)
index 0075f7f..548c9de 100644 (file)
@@ -36,33 +36,6 @@ class StyleResolver;
 
 namespace Style {
 
-inline bool isValidVisitedLinkProperty(CSSPropertyID id)
-{
-    switch (id) {
-    case CSSPropertyBackgroundColor:
-    case CSSPropertyBorderLeftColor:
-    case CSSPropertyBorderRightColor:
-    case CSSPropertyBorderTopColor:
-    case CSSPropertyBorderBottomColor:
-    case CSSPropertyCaretColor:
-    case CSSPropertyColor:
-    case CSSPropertyOutlineColor:
-    case CSSPropertyColumnRuleColor:
-    case CSSPropertyTextDecorationColor:
-    case CSSPropertyWebkitTextEmphasisColor:
-    case CSSPropertyWebkitTextFillColor:
-    case CSSPropertyWebkitTextStrokeColor:
-    case CSSPropertyFill:
-    case CSSPropertyStroke:
-    case CSSPropertyStrokeColor:
-        return true;
-    default:
-        break;
-    }
-
-    return false;
-}
-
 class PropertyCascade {
     WTF_MAKE_FAST_ALLOCATED;
 public:
index 132896c..d4c600e 100644 (file)
 #include "Settings.h"
 #include "StyleBuilderGenerated.h"
 #include "StyleFontSizeFunctions.h"
-#include "StyleResolver.h"
 
 namespace WebCore {
 namespace Style {
 
 static const CSSPropertyID firstLowPriorityProperty = static_cast<CSSPropertyID>(lastHighPriorityProperty + 1);
 
-static PropertyCascade::Direction directionFromStyle(const RenderStyle& style)
+inline PropertyCascade::Direction directionFromStyle(const RenderStyle& style)
 {
     return { style.direction(), style.writingMode() };
 }
 
-Builder::Builder(RenderStyle& style, const StyleResolver& resolver, const MatchResult& matchResult, OptionSet<CascadeLevel> cascadeLevels, PropertyCascade::IncludedProperties includedProperties)
-    : m_cascade(matchResult, cascadeLevels, includedProperties, directionFromStyle(style))
-    , m_state(*this, style, *resolver.parentStyle(), resolver.rootElementStyle(), resolver.document(), resolver.element())
+inline bool isValidVisitedLinkProperty(CSSPropertyID id)
 {
-    ASSERT(resolver.parentStyle());
+    switch (id) {
+    case CSSPropertyBackgroundColor:
+    case CSSPropertyBorderLeftColor:
+    case CSSPropertyBorderRightColor:
+    case CSSPropertyBorderTopColor:
+    case CSSPropertyBorderBottomColor:
+    case CSSPropertyCaretColor:
+    case CSSPropertyColor:
+    case CSSPropertyOutlineColor:
+    case CSSPropertyColumnRuleColor:
+    case CSSPropertyTextDecorationColor:
+    case CSSPropertyWebkitTextEmphasisColor:
+    case CSSPropertyWebkitTextFillColor:
+    case CSSPropertyWebkitTextStrokeColor:
+    case CSSPropertyFill:
+    case CSSPropertyStroke:
+    case CSSPropertyStrokeColor:
+        return true;
+    default:
+        break;
+    }
+
+    return false;
 }
 
-Builder::Builder(StyleResolver& resolver, const MatchResult& matchResult, OptionSet<CascadeLevel> cascadeLevels, PropertyCascade::IncludedProperties includedProperties)
-    : Builder(*resolver.style(), resolver, matchResult, cascadeLevels, includedProperties)
+Builder::Builder(RenderStyle& style, BuilderContext&& context, const MatchResult& matchResult, OptionSet<CascadeLevel> cascadeLevels, PropertyCascade::IncludedProperties includedProperties)
+    : m_cascade(matchResult, cascadeLevels, includedProperties, directionFromStyle(style))
+    , m_state(*this, style, WTFMove(context))
 {
-    ASSERT(resolver.style());
 }
 
 Builder::~Builder() = default;
@@ -97,9 +116,12 @@ void Builder::applyLowPriorityProperties()
     ASSERT(!m_state.fontDirty());
 }
 
-void Builder::applyPropertyValue(CSSPropertyID propertyID, CSSValue& value)
+void Builder::applyPropertyValue(CSSPropertyID propertyID, CSSValue* value)
 {
-    applyProperty(propertyID, value, SelectorChecker::MatchDefault);
+    if (!value)
+        return;
+
+    applyProperty(propertyID, *value, SelectorChecker::MatchDefault);
 
     m_state.updateFont();
 }
index 463d857..10ae676 100644 (file)
@@ -35,8 +35,7 @@ namespace Style {
 class Builder {
     WTF_MAKE_FAST_ALLOCATED;
 public:
-    Builder(RenderStyle&, const StyleResolver&, const MatchResult&, OptionSet<CascadeLevel>, PropertyCascade::IncludedProperties = PropertyCascade::IncludedProperties::All);
-    Builder(StyleResolver&, const MatchResult&, OptionSet<CascadeLevel>, PropertyCascade::IncludedProperties = PropertyCascade::IncludedProperties::All);
+    Builder(RenderStyle&, BuilderContext&&, const MatchResult&, OptionSet<CascadeLevel>, PropertyCascade::IncludedProperties = PropertyCascade::IncludedProperties::All);
     ~Builder();
 
     void applyAllProperties();
@@ -46,7 +45,7 @@ public:
     void applyProperty(CSSPropertyID propertyID) { applyProperties(propertyID, propertyID); }
     void applyCustomProperty(const String& name);
 
-    void applyPropertyValue(CSSPropertyID, CSSValue&);
+    void applyPropertyValue(CSSPropertyID, CSSValue*);
 
     BuilderState& state() { return m_state; }
 
index 015116b..ce08cae 100644 (file)
 namespace WebCore {
 namespace Style {
 
-BuilderState::BuilderState(Builder& builder, RenderStyle& style, const RenderStyle& parentStyle, const RenderStyle* rootElementStyle, const Document& document, const Element* element)
+BuilderState::BuilderState(Builder& builder, RenderStyle& style, BuilderContext&& context)
     : m_builder(builder)
     , m_styleMap(*this)
     , m_style(style)
-    , m_parentStyle(parentStyle)
-    , m_rootElementStyle(rootElementStyle)
-    , m_cssToLengthConversionData(&style, rootElementStyle, document.renderView())
-    , m_document(document)
-    , m_element(element)
+    , m_context(WTFMove(context))
+    , m_cssToLengthConversionData(&style, rootElementStyle(), document().renderView())
 {
 }
 
@@ -359,7 +356,7 @@ void BuilderState::updateFontForTextSizeAdjust()
 
 void BuilderState::updateFontForZoomChange()
 {
-    if (m_style.effectiveZoom() == m_parentStyle.effectiveZoom() && m_style.textZoom() == m_parentStyle.textZoom())
+    if (m_style.effectiveZoom() == parentStyle().effectiveZoom() && m_style.textZoom() == parentStyle().textZoom())
         return;
 
     const auto& childFont = m_style.fontDescription();
@@ -376,7 +373,7 @@ void BuilderState::updateFontForGenericFamilyChange()
     if (childFont.isAbsoluteSize())
         return;
 
-    const auto& parentFont = m_parentStyle.fontDescription();
+    const auto& parentFont = parentStyle().fontDescription();
     if (childFont.useFixedDefaultSize() == parentFont.useFixedDefaultSize())
         return;
 
index e5864ef..725838c 100644 (file)
@@ -41,18 +41,25 @@ namespace Style {
 
 class Builder;
 
+struct BuilderContext {
+    Ref<const Document> document;
+    const RenderStyle& parentStyle;
+    const RenderStyle* rootElementStyle = nullptr;
+    RefPtr<const Element> element = nullptr;
+};
+
 class BuilderState {
 public:
-    BuilderState(Builder&, RenderStyle&, const RenderStyle& parentStyle, const RenderStyle* rootElementStyle, const Document&, const Element*);
+    BuilderState(Builder&, RenderStyle&, BuilderContext&&);
 
     Builder& builder() { return m_builder; }
 
     RenderStyle& style() { return m_style; }
-    const RenderStyle& parentStyle() const { return m_parentStyle; }
-    const RenderStyle* rootElementStyle() const { return m_rootElementStyle; }
+    const RenderStyle& parentStyle() const { return m_context.parentStyle; }
+    const RenderStyle* rootElementStyle() const { return m_context.rootElementStyle; }
 
-    const Document& document() const { return m_document.get(); }
-    const Element* element() const { return m_element.get(); }
+    const Document& document() const { return m_context.document.get(); }
+    const Element* element() const { return m_context.element.get(); }
 
     void setFontDescription(FontCascadeDescription&& fontDescription) { m_fontDirty |= m_style.setFontDescription(WTFMove(fontDescription)); }
     void setFontSize(FontCascadeDescription&, float size);
@@ -65,7 +72,7 @@ public:
     void setFontDirty() { m_fontDirty = true; }
 
     const FontCascadeDescription& fontDescription() { return m_style.fontDescription(); }
-    const FontCascadeDescription& parentFontDescription() { return m_parentStyle.fontDescription(); }
+    const FontCascadeDescription& parentFontDescription() { return parentStyle().fontDescription(); }
 
     // FIXME: These are mutually exclusive, clean up the code to take that into account.
     bool applyPropertyToRegularStyle() const { return m_linkMatch != SelectorChecker::MatchVisited; }
@@ -105,14 +112,10 @@ private:
     CSSToStyleMap m_styleMap;
 
     RenderStyle& m_style;
-    const RenderStyle& m_parentStyle;
-    const RenderStyle* m_rootElementStyle;
+    const BuilderContext m_context;
 
     const CSSToLengthConversionData m_cssToLengthConversionData;
 
-    Ref<const Document> m_document;
-    RefPtr<const Element> m_element;
-
     Bitmap<numCSSProperties> m_appliedProperties;
     HashSet<String> m_appliedCustomProperties;
     Bitmap<numCSSProperties> m_inProgressProperties;