Move StyleResolver::applyProperty to PropertyCascade
authorantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 26 Oct 2019 15:15:20 +0000 (15:15 +0000)
committerantti@apple.com <antti@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Sat, 26 Oct 2019 15:15:20 +0000 (15:15 +0000)
https://bugs.webkit.org/show_bug.cgi?id=203458

Reviewed by Zalan Bujtas.

Move the more of the property applying code out of StyleResolver.

* css/StyleResolver.cpp:
(WebCore::StyleResolver::applyPropertyToCurrentStyle):
(WebCore::isValidVisitedLinkProperty): Deleted.
(WebCore::StyleResolver::applyProperty): Deleted.
(WebCore::StyleResolver::resolvedVariableValue const): Deleted.
* css/StyleResolver.h:
* style/PropertyCascade.cpp:
(WebCore::Style::isValidVisitedLinkProperty):
(WebCore::Style::PropertyCascade::applyCustomProperty):
(WebCore::Style::PropertyCascade::propertyCascadeForRollback):
(WebCore::Style::PropertyCascade::applyProperty):
(WebCore::Style::PropertyCascade::resolveValue):
(WebCore::Style::PropertyCascade::resolvedVariableValue):
* style/PropertyCascade.h:
(WebCore::Style::PropertyCascade::property const):
(WebCore::Style::PropertyCascade::property): Deleted.
(WebCore::Style::PropertyCascade::hasAppliedProperty const): Deleted.

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

Source/WebCore/ChangeLog
Source/WebCore/css/StyleResolver.cpp
Source/WebCore/css/StyleResolver.h
Source/WebCore/style/PropertyCascade.cpp
Source/WebCore/style/PropertyCascade.h

index 9ae987e..2f7a30b 100644 (file)
@@ -1,3 +1,30 @@
+2019-10-26  Antti Koivisto  <antti@apple.com>
+
+        Move StyleResolver::applyProperty to PropertyCascade
+        https://bugs.webkit.org/show_bug.cgi?id=203458
+
+        Reviewed by Zalan Bujtas.
+
+        Move the more of the property applying code out of StyleResolver.
+
+        * css/StyleResolver.cpp:
+        (WebCore::StyleResolver::applyPropertyToCurrentStyle):
+        (WebCore::isValidVisitedLinkProperty): Deleted.
+        (WebCore::StyleResolver::applyProperty): Deleted.
+        (WebCore::StyleResolver::resolvedVariableValue const): Deleted.
+        * css/StyleResolver.h:
+        * style/PropertyCascade.cpp:
+        (WebCore::Style::isValidVisitedLinkProperty):
+        (WebCore::Style::PropertyCascade::applyCustomProperty):
+        (WebCore::Style::PropertyCascade::propertyCascadeForRollback):
+        (WebCore::Style::PropertyCascade::applyProperty):
+        (WebCore::Style::PropertyCascade::resolveValue):
+        (WebCore::Style::PropertyCascade::resolvedVariableValue):
+        * style/PropertyCascade.h:
+        (WebCore::Style::PropertyCascade::property const):
+        (WebCore::Style::PropertyCascade::property): Deleted.
+        (WebCore::Style::PropertyCascade::hasAppliedProperty const): Deleted.
+
 2019-10-26  Zalan Bujtas  <zalan@apple.com>
 
         [LFC][IFC] Completely collapsed runs should not have advance width
index 81cec97..24ebf06 100644 (file)
@@ -42,7 +42,6 @@
 #include "CSSImageValue.h"
 #include "CSSKeyframeRule.h"
 #include "CSSKeyframesRule.h"
-#include "CSSPaintImageValue.h"
 #include "CSSParser.h"
 #include "CSSPrimitiveValueMappings.h"
 #include "CSSPropertyNames.h"
@@ -93,7 +92,6 @@
 #include "Settings.h"
 #include "ShadowRoot.h"
 #include "SharedStringHash.h"
-#include "StyleBuilder.h"
 #include "StyleColor.h"
 #include "StyleCachedImage.h"
 #include "StyleFontSizeFunctions.h"
@@ -1453,37 +1451,12 @@ void StyleResolver::applyPropertyToStyle(CSSPropertyID id, CSSValue* value, std:
 
 void StyleResolver::applyPropertyToCurrentStyle(CSSPropertyID id, CSSValue* value)
 {
+    if (!value)
+        return;
     MatchResult matchResult;
     Style::PropertyCascade cascade(*this, matchResult, { }, { }, { });
     if (value)
-        applyProperty(id, value, cascade);
-}
-
-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;
+        cascade.applyProperty(id, *value);
 }
 
 // SVG handles zooming in a different way compared to CSS. The whole document is scaled instead
@@ -1505,119 +1478,6 @@ bool StyleResolver::useSVGZoomRulesForLength() const
     return is<SVGElement>(m_state.element()) && !(is<SVGSVGElement>(*m_state.element()) && m_state.element()->parentNode());
 }
 
-void StyleResolver::applyProperty(CSSPropertyID id, CSSValue* value, Style::PropertyCascade& cascade, SelectorChecker::LinkMatchMask linkMatchMask)
-{
-    ASSERT_WITH_MESSAGE(!isShorthandCSSProperty(id), "Shorthand property id = %d wasn't expanded at parsing time", id);
-
-    State& state = m_state;
-
-    RefPtr<CSSValue> valueToApply = value;
-    if (value->hasVariableReferences()) {
-        valueToApply = resolvedVariableValue(id, *value, cascade);
-        // If the cascade has already applied this id, then we detected a cycle, and this value should be unset.
-        if (!valueToApply || cascade.hasAppliedProperty(id)) {
-            if (CSSProperty::isInheritedProperty(id))
-                valueToApply = CSSValuePool::singleton().createInheritedValue();
-            else
-                valueToApply = CSSValuePool::singleton().createExplicitInitialValue();
-        }
-    }
-
-    if (CSSProperty::isDirectionAwareProperty(id)) {
-        CSSPropertyID newId = CSSProperty::resolveDirectionAwareProperty(id, state.style()->direction(), state.style()->writingMode());
-        ASSERT(newId != id);
-        return applyProperty(newId, valueToApply.get(), cascade, linkMatchMask);
-    }
-
-    CSSValue* valueToCheckForInheritInitial = valueToApply.get();
-    CSSCustomPropertyValue* customPropertyValue = nullptr;
-    CSSValueID customPropertyValueID = CSSValueInvalid;
-
-    CSSRegisteredCustomProperty* customPropertyRegistered = nullptr;
-
-    if (id == CSSPropertyCustom) {
-        customPropertyValue = &downcast<CSSCustomPropertyValue>(*valueToApply);
-        ASSERT(customPropertyValue->isResolved());
-        if (WTF::holds_alternative<CSSValueID>(customPropertyValue->value()))
-            customPropertyValueID = WTF::get<CSSValueID>(customPropertyValue->value());
-        auto& name = customPropertyValue->name();
-        customPropertyRegistered = document().getCSSRegisteredCustomPropertySet().get(name);
-    }
-
-    bool isInherit = state.parentStyle() ? valueToCheckForInheritInitial->isInheritedValue() || customPropertyValueID == CSSValueInherit : false;
-    bool isInitial = valueToCheckForInheritInitial->isInitialValue() || customPropertyValueID == CSSValueInitial || (!state.parentStyle() && (valueToCheckForInheritInitial->isInheritedValue() || customPropertyValueID == CSSValueInherit));
-
-    bool isUnset = valueToCheckForInheritInitial->isUnsetValue() || customPropertyValueID == CSSValueUnset;
-    bool isRevert = valueToCheckForInheritInitial->isRevertValue() || customPropertyValueID == CSSValueRevert;
-
-    if (isRevert) {
-        if (state.cascadeLevel() == Style::CascadeLevel::UserAgent)
-            isUnset = true;
-        else {
-            auto* rollback = cascade.propertyCascadeForRollback(state.cascadeLevel());
-            ASSERT(rollback);
-
-            // With the cascade built, we need to obtain the property and apply it. If the property is
-            // not present, then we behave like "unset." Otherwise we apply the property instead of
-            // our own.
-            if (customPropertyValue) {
-                if (customPropertyRegistered && customPropertyRegistered->inherits && rollback->hasCustomProperty(customPropertyValue->name())) {
-                    auto property = rollback->customProperty(customPropertyValue->name());
-                    if (property.cssValue[linkMatchMask])
-                        applyProperty(property.id, property.cssValue[linkMatchMask], cascade, linkMatchMask);
-                    return;
-                }
-            } else if (rollback->hasProperty(id)) {
-                auto& property = rollback->property(id);
-                if (property.cssValue[linkMatchMask])
-                    applyProperty(property.id, property.cssValue[linkMatchMask], cascade, linkMatchMask);
-                return;
-            }
-
-            isUnset = true;
-        }
-    }
-
-    if (isUnset) {
-        if (CSSProperty::isInheritedProperty(id))
-            isInherit = true;
-        else
-            isInitial = true;
-    }
-
-    ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit
-
-    if (!state.applyPropertyToRegularStyle() && (!state.applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) {
-        // Limit the properties that can be applied to only the ones honored by :visited.
-        return;
-    }
-
-    if (isInherit && !CSSProperty::isInheritedProperty(id))
-        state.style()->setHasExplicitlyInheritedProperties();
-
-#if ENABLE(CSS_PAINTING_API)
-    if (is<CSSPaintImageValue>(*valueToApply)) {
-        auto& name = downcast<CSSPaintImageValue>(*valueToApply).name();
-        if (auto* paintWorklet = document().paintWorkletGlobalScopeForName(name)) {
-            auto locker = holdLock(paintWorklet->paintDefinitionLock());
-            if (auto* registration = paintWorklet->paintDefinitionMap().get(name)) {
-                for (auto& property : registration->inputProperties)
-                    state.style()->addCustomPaintWatchProperty(property);
-            }
-        }
-    }
-#endif
-
-    // Use the generated StyleBuilder.
-    StyleBuilder::applyProperty(id, *this, *valueToApply, isInitial, isInherit, customPropertyRegistered);
-}
-
-RefPtr<CSSValue> StyleResolver::resolvedVariableValue(CSSPropertyID propID, const CSSValue& value, Style::PropertyCascade& cascade) const
-{
-    CSSParser parser(document());
-    return parser.parseValueWithVariableReferences(propID, value, cascade);
-}
-
 RefPtr<StyleImage> StyleResolver::styleImage(CSSValue& value)
 {
     if (is<CSSImageGeneratorValue>(value)) {
index c07c8ef..57c98a1 100644 (file)
@@ -327,12 +327,8 @@ public:
     void setWritingMode(WritingMode writingMode) { m_state.setWritingMode(writingMode); }
     void setTextOrientation(TextOrientation textOrientation) { m_state.setTextOrientation(textOrientation); }
 
-    RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSValue&, Style::PropertyCascade&) const;
-
     bool adjustRenderStyleForTextAutosizing(RenderStyle&, const Element&);
 
-    void applyProperty(CSSPropertyID, CSSValue*, Style::PropertyCascade&, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault);
-
 private:
     void cacheBorderAndBackground();
 
index 53f2594..c40e04a 100644 (file)
 #include "config.h"
 #include "PropertyCascade.h"
 
+#include "CSSPaintImageValue.h"
+#include "CSSValuePool.h"
+#include "PaintWorkletGlobalScope.h"
+#include "StyleBuilder.h"
+#include "StylePropertyShorthand.h"
 #include "StyleResolver.h"
 
 namespace WebCore {
@@ -93,6 +98,33 @@ static inline bool isValidMarkerStyleProperty(CSSPropertyID id)
     return false;
 }
 
+static 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;
+}
+
 #if ENABLE(VIDEO_TRACK)
 static inline bool isValidCueStyleProperty(CSSPropertyID id)
 {
@@ -404,7 +436,7 @@ void PropertyCascade::applyCustomProperty(const String& name)
         m_applyState.inProgressPropertiesCustom.add(name);
 
         if (WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value())) {
-            RefPtr<CSSValue> parsedValue = m_styleResolver.resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), *this);
+            RefPtr<CSSValue> parsedValue = resolvedVariableValue(CSSPropertyCustom, valueToApply.get());
 
             if (m_applyState.appliedCustomProperties.contains(name))
                 return; // There was a cycle and the value was reset, so bail.
@@ -430,7 +462,7 @@ void PropertyCascade::applyCustomProperty(const String& name)
                 m_styleResolver.state().setApplyPropertyToRegularStyle(false);
                 m_styleResolver.state().setApplyPropertyToVisitedLinkStyle(true);
             }
-            m_styleResolver.applyProperty(CSSPropertyCustom, valueToApply.ptr(), *this, index);
+            applyProperty(CSSPropertyCustom, valueToApply.get(), index);
         }
     }
 
@@ -447,30 +479,30 @@ void PropertyCascade::applyCustomProperty(const String& name)
 
         if (inCycle && WTF::holds_alternative<Ref<CSSVariableReferenceValue>>(valueToApply->value())) {
             // Resolve this value so that we reset its dependencies.
-            m_styleResolver.resolvedVariableValue(CSSPropertyCustom, valueToApply.get(), *this);
+            resolvedVariableValue(CSSPropertyCustom, valueToApply.get());
         }
     }
 }
 
-PropertyCascade* PropertyCascade::propertyCascadeForRollback(CascadeLevel cascadeLevel)
+const PropertyCascade* PropertyCascade::propertyCascadeForRollback(CascadeLevel cascadeLevel)
 {
     switch (cascadeLevel) {
     case CascadeLevel::Author:
         if (!m_authorRollbackCascade) {
             auto cascadeLevels = OptionSet<CascadeLevel> { CascadeLevel::UserAgent, CascadeLevel::User };
-            m_authorRollbackCascade = makeUnique<PropertyCascade>(m_styleResolver, m_matchResult, cascadeLevels, m_direction, m_writingMode, m_includedProperties);
+            m_authorRollbackCascade = makeUnique<const PropertyCascade>(m_styleResolver, m_matchResult, cascadeLevels, m_direction, m_writingMode, m_includedProperties);
         }
         return m_authorRollbackCascade.get();
 
     case CascadeLevel::User:
         if (!m_userRollbackCascade) {
             auto cascadeLevels = OptionSet<CascadeLevel> { CascadeLevel::UserAgent };
-            m_userRollbackCascade = makeUnique<PropertyCascade>(m_styleResolver, m_matchResult, cascadeLevels, m_direction, m_writingMode, m_includedProperties);
+            m_userRollbackCascade = makeUnique<const PropertyCascade>(m_styleResolver, m_matchResult, cascadeLevels, m_direction, m_writingMode, m_includedProperties);
         }
         return m_userRollbackCascade.get();
 
     case CascadeLevel::UserAgent:
-        break;
+        return nullptr;
     }
     ASSERT_NOT_REACHED();
     return nullptr;
@@ -485,7 +517,7 @@ inline void PropertyCascade::applyProperty(const Property& property)
     if (property.cssValue[SelectorChecker::MatchDefault]) {
         state.setApplyPropertyToRegularStyle(true);
         state.setApplyPropertyToVisitedLinkStyle(false);
-        m_styleResolver.applyProperty(property.id, property.cssValue[SelectorChecker::MatchDefault], *this, SelectorChecker::MatchDefault);
+        applyProperty(property.id, *property.cssValue[SelectorChecker::MatchDefault], SelectorChecker::MatchDefault);
     }
 
     if (state.style()->insideLink() == InsideLink::NotInside)
@@ -494,18 +526,129 @@ inline void PropertyCascade::applyProperty(const Property& property)
     if (property.cssValue[SelectorChecker::MatchLink]) {
         state.setApplyPropertyToRegularStyle(true);
         state.setApplyPropertyToVisitedLinkStyle(false);
-        m_styleResolver.applyProperty(property.id, property.cssValue[SelectorChecker::MatchLink], *this, SelectorChecker::MatchLink);
+        applyProperty(property.id, *property.cssValue[SelectorChecker::MatchLink], SelectorChecker::MatchLink);
     }
 
     if (property.cssValue[SelectorChecker::MatchVisited]) {
         state.setApplyPropertyToRegularStyle(false);
         state.setApplyPropertyToVisitedLinkStyle(true);
-        m_styleResolver.applyProperty(property.id, property.cssValue[SelectorChecker::MatchVisited], *this, SelectorChecker::MatchVisited);
+        applyProperty(property.id, *property.cssValue[SelectorChecker::MatchVisited], SelectorChecker::MatchVisited);
     }
 
     state.setApplyPropertyToRegularStyle(true);
     state.setApplyPropertyToVisitedLinkStyle(false);
 }
 
+void PropertyCascade::applyProperty(CSSPropertyID id, CSSValue& value, SelectorChecker::LinkMatchMask linkMatchMask)
+{
+    ASSERT_WITH_MESSAGE(!isShorthandCSSProperty(id), "Shorthand property id = %d wasn't expanded at parsing time", id);
+
+    auto valueToApply = resolveValue(id, value);
+
+    if (CSSProperty::isDirectionAwareProperty(id)) {
+        CSSPropertyID newId = CSSProperty::resolveDirectionAwareProperty(id, m_direction, m_writingMode);
+        ASSERT(newId != id);
+        return applyProperty(newId, valueToApply.get(), linkMatchMask);
+    }
+
+    CSSCustomPropertyValue* customPropertyValue = nullptr;
+    CSSValueID customPropertyValueID = CSSValueInvalid;
+    CSSRegisteredCustomProperty* customPropertyRegistered = nullptr;
+
+    if (id == CSSPropertyCustom) {
+        customPropertyValue = downcast<CSSCustomPropertyValue>(valueToApply.ptr());
+        ASSERT(customPropertyValue->isResolved());
+        if (WTF::holds_alternative<CSSValueID>(customPropertyValue->value()))
+            customPropertyValueID = WTF::get<CSSValueID>(customPropertyValue->value());
+        auto& name = customPropertyValue->name();
+        customPropertyRegistered = m_styleResolver.document().getCSSRegisteredCustomPropertySet().get(name);
+    }
+
+    auto& state = m_styleResolver.state();
+    bool isInherit = state.parentStyle() ? valueToApply->isInheritedValue() || customPropertyValueID == CSSValueInherit : false;
+    bool isInitial = valueToApply->isInitialValue() || customPropertyValueID == CSSValueInitial || (!state.parentStyle() && (valueToApply->isInheritedValue() || customPropertyValueID == CSSValueInherit));
+
+    bool isUnset = valueToApply->isUnsetValue() || customPropertyValueID == CSSValueUnset;
+    bool isRevert = valueToApply->isRevertValue() || customPropertyValueID == CSSValueRevert;
+
+    if (isRevert) {
+        if (auto* rollback = propertyCascadeForRollback(state.cascadeLevel())) {
+            // With the rollback cascade built, we need to obtain the property and apply it. If the property is
+            // not present, then we behave like "unset." Otherwise we apply the property instead of
+            // our own.
+            if (customPropertyValue) {
+                if (customPropertyRegistered && customPropertyRegistered->inherits && rollback->hasCustomProperty(customPropertyValue->name())) {
+                    auto property = rollback->customProperty(customPropertyValue->name());
+                    if (property.cssValue[linkMatchMask])
+                        applyProperty(property.id, *property.cssValue[linkMatchMask], linkMatchMask);
+                    return;
+                }
+            } else if (rollback->hasProperty(id)) {
+                auto& property = rollback->property(id);
+                if (property.cssValue[linkMatchMask])
+                    applyProperty(property.id, *property.cssValue[linkMatchMask], linkMatchMask);
+                return;
+            }
+        }
+
+        isUnset = true;
+    }
+
+    if (isUnset) {
+        if (CSSProperty::isInheritedProperty(id))
+            isInherit = true;
+        else
+            isInitial = true;
+    }
+
+    ASSERT(!isInherit || !isInitial); // isInherit -> !isInitial && isInitial -> !isInherit
+
+    if (!state.applyPropertyToRegularStyle() && (!state.applyPropertyToVisitedLinkStyle() || !isValidVisitedLinkProperty(id))) {
+        // Limit the properties that can be applied to only the ones honored by :visited.
+        return;
+    }
+
+    if (isInherit && !CSSProperty::isInheritedProperty(id))
+        state.style()->setHasExplicitlyInheritedProperties();
+
+#if ENABLE(CSS_PAINTING_API)
+    if (is<CSSPaintImageValue>(valueToApply)) {
+        auto& name = downcast<CSSPaintImageValue>(valueToApply.get()).name();
+        if (auto* paintWorklet = m_styleResolver.document().paintWorkletGlobalScopeForName(name)) {
+            auto locker = holdLock(paintWorklet->paintDefinitionLock());
+            if (auto* registration = paintWorklet->paintDefinitionMap().get(name)) {
+                for (auto& property : registration->inputProperties)
+                    state.style()->addCustomPaintWatchProperty(property);
+            }
+        }
+    }
+#endif
+
+    // Use the generated StyleBuilder.
+    StyleBuilder::applyProperty(id, m_styleResolver, valueToApply.get(), isInitial, isInherit, customPropertyRegistered);
+}
+
+Ref<CSSValue> PropertyCascade::resolveValue(CSSPropertyID propertyID, CSSValue& value)
+{
+    if (!value.hasVariableReferences())
+        return value;
+    
+    auto variableValue = resolvedVariableValue(propertyID, value);
+    // If the cascade has already applied this id, then we detected a cycle, and this value should be unset.
+    if (!variableValue || m_applyState.appliedProperties.get(propertyID)) {
+        if (CSSProperty::isInheritedProperty(propertyID))
+            return CSSValuePool::singleton().createInheritedValue();
+        return CSSValuePool::singleton().createExplicitInitialValue();
+    }
+
+    return *variableValue;
+}
+
+RefPtr<CSSValue> PropertyCascade::resolvedVariableValue(CSSPropertyID propID, const CSSValue& value)
+{
+    CSSParser parser(m_styleResolver.document());
+    return parser.parseValueWithVariableReferences(propID, value, *this);
+}
+
 }
 }
index 4288b9b..ee7fe16 100644 (file)
@@ -60,20 +60,18 @@ public:
     };
 
     bool hasProperty(CSSPropertyID) const;
-    Property& property(CSSPropertyID);
+    const Property& property(CSSPropertyID) const;
 
     bool hasCustomProperty(const String&) const;
     Property customProperty(const String&) const;
 
-    bool hasAppliedProperty(CSSPropertyID) const;
-
     void applyProperties(int firstProperty, int lastProperty);
     void applyDeferredProperties();
 
     void applyCustomProperties();
     void applyCustomProperty(const String& name);
 
-    PropertyCascade* propertyCascadeForRollback(CascadeLevel);
+    void applyProperty(CSSPropertyID, CSSValue&, SelectorChecker::LinkMatchMask = SelectorChecker::MatchDefault);
 
 private:
     bool addNormalMatches(CascadeLevel);
@@ -84,17 +82,22 @@ private:
     void setDeferred(CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel, ScopeOrdinal);
     static void setPropertyInternal(Property&, CSSPropertyID, CSSValue&, unsigned linkMatchType, CascadeLevel, ScopeOrdinal);
 
+    const PropertyCascade* propertyCascadeForRollback(CascadeLevel);
+
     enum CustomPropertyCycleTracking { Enabled = 0, Disabled };
     template<CustomPropertyCycleTracking trackCycles>
     void applyPropertiesImpl(int firstProperty, int lastProperty);
     void applyProperty(const Property&);
 
+    Ref<CSSValue> resolveValue(CSSPropertyID, CSSValue&);
+    RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSValue&);
+
     StyleResolver& m_styleResolver;
-    const MatchResult& m_matchResult;
-    IncludedProperties m_includedProperties;
 
-    TextDirection m_direction;
-    WritingMode m_writingMode;
+    const MatchResult& m_matchResult;
+    const IncludedProperties m_includedProperties;
+    const TextDirection m_direction;
+    const WritingMode m_writingMode;
 
     Property m_properties[numCSSProperties + 2];
     std::bitset<numCSSProperties + 2> m_propertyIsPresent;
@@ -113,8 +116,8 @@ private:
 
     ApplyState m_applyState;
 
-    std::unique_ptr<PropertyCascade> m_authorRollbackCascade;
-    std::unique_ptr<PropertyCascade> m_userRollbackCascade;
+    std::unique_ptr<const PropertyCascade> m_authorRollbackCascade;
+    std::unique_ptr<const PropertyCascade> m_userRollbackCascade;
 };
 
 inline bool PropertyCascade::hasProperty(CSSPropertyID id) const
@@ -123,7 +126,7 @@ inline bool PropertyCascade::hasProperty(CSSPropertyID id) const
     return m_propertyIsPresent[id];
 }
 
-inline PropertyCascade::Property& PropertyCascade::property(CSSPropertyID id)
+inline const PropertyCascade::Property& PropertyCascade::property(CSSPropertyID id) const
 {
     return m_properties[id];
 }
@@ -138,10 +141,5 @@ inline PropertyCascade::Property PropertyCascade::customProperty(const String& n
     return m_customProperties.get(name);
 }
 
-inline bool PropertyCascade::hasAppliedProperty(CSSPropertyID propertyID) const
-{
-    return m_applyState.appliedProperties.get(propertyID);
-}
-
 }
 }