Diff
Modified: trunk/LayoutTests/ChangeLog (285485 => 285486)
--- trunk/LayoutTests/ChangeLog 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/LayoutTests/ChangeLog 2021-11-09 09:29:43 UTC (rev 285486)
@@ -1,3 +1,13 @@
+2021-11-09 Antti Koivisto <[email protected]>
+
+ [CSS Cascade Layers] Support 'revert-layer' value
+ https://bugs.webkit.org/show_bug.cgi?id=232236
+ <rdar://problem/84879369>
+
+ Reviewed by Simon Fraser.
+
+ * TestExpectations:
+
2021-11-09 Arcady Goldmints-Orlov <[email protected]>
[GLIB] Update test expectations and baselines. Unreviewed test gardening.
Modified: trunk/LayoutTests/TestExpectations (285485 => 285486)
--- trunk/LayoutTests/TestExpectations 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/LayoutTests/TestExpectations 2021-11-09 09:29:43 UTC (rev 285486)
@@ -2149,13 +2149,6 @@
imported/w3c/web-platform-tests/css/css-cascade/important-prop.html [ ImageOnlyFailure ]
webkit.org/b/187093 [ Debug ] imported/w3c/web-platform-tests/css/css-cascade/all-prop-initial-xml.html [ Skip ]
-webkit.org/b/232236 imported/w3c/web-platform-tests/css/css-cascade/revert-layer-001.html [ ImageOnlyFailure ]
-webkit.org/b/232236 imported/w3c/web-platform-tests/css/css-cascade/revert-layer-002.html [ ImageOnlyFailure ]
-webkit.org/b/232236 imported/w3c/web-platform-tests/css/css-cascade/revert-layer-003.html [ ImageOnlyFailure ]
-webkit.org/b/232236 imported/w3c/web-platform-tests/css/css-cascade/revert-layer-004.html [ ImageOnlyFailure ]
-webkit.org/b/232236 imported/w3c/web-platform-tests/css/css-cascade/revert-layer-005.html [ ImageOnlyFailure ]
-webkit.org/b/232236 imported/w3c/web-platform-tests/css/css-cascade/revert-layer-006.html [ ImageOnlyFailure ]
-webkit.org/b/232236 imported/w3c/web-platform-tests/css/css-cascade/revert-layer-007.html [ ImageOnlyFailure ]
webkit.org/b/148801 imported/w3c/web-platform-tests/css/css-color/t422-rgba-onscreen-b.xht [ ImageOnlyFailure ]
webkit.org/b/148801 imported/w3c/web-platform-tests/css/css-color/t422-rgba-onscreen-multiple-boxes-c.xht [ ImageOnlyFailure ]
Modified: trunk/LayoutTests/imported/w3c/ChangeLog (285485 => 285486)
--- trunk/LayoutTests/imported/w3c/ChangeLog 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/LayoutTests/imported/w3c/ChangeLog 2021-11-09 09:29:43 UTC (rev 285486)
@@ -1,3 +1,13 @@
+2021-11-09 Antti Koivisto <[email protected]>
+
+ [CSS Cascade Layers] Support 'revert-layer' value
+ https://bugs.webkit.org/show_bug.cgi?id=232236
+ <rdar://problem/84879369>
+
+ Reviewed by Simon Fraser.
+
+ * web-platform-tests/css/css-cascade/revert-layer-008-expected.txt:
+
2021-11-09 Arcady Goldmints-Orlov <[email protected]>
[GLIB] Update test expectations and baselines. Unreviewed test gardening.
Modified: trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/revert-layer-008-expected.txt (285485 => 285486)
--- trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/revert-layer-008-expected.txt 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/LayoutTests/imported/w3c/web-platform-tests/css/css-cascade/revert-layer-008-expected.txt 2021-11-09 09:29:43 UTC (rev 285486)
@@ -1,3 +1,3 @@
-FAIL 'revert-layer' should revert font-size to 20px and trigger a smooth transition assert_equals: expected "15px" but got "10px"
+PASS 'revert-layer' should revert font-size to 20px and trigger a smooth transition
Modified: trunk/Source/WebCore/ChangeLog (285485 => 285486)
--- trunk/Source/WebCore/ChangeLog 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/ChangeLog 2021-11-09 09:29:43 UTC (rev 285486)
@@ -1,3 +1,95 @@
+2021-11-09 Antti Koivisto <[email protected]>
+
+ [CSS Cascade Layers] Support 'revert-layer' value
+ https://bugs.webkit.org/show_bug.cgi?id=232236
+ <rdar://problem/84879369>
+
+ Reviewed by Simon Fraser.
+
+ 'revert-layer' keyword rolls back the value computed by the cascade to the one coming from the layer below.
+
+ https://www.w3.org/TR/css-cascade-5/#revert-layer
+
+ * css/CSSPrimitiveValue.h:
+ * css/CSSValue.cpp:
+ (WebCore::CSSValue::isRevertLayerValue const):
+ * css/CSSValue.h:
+ * css/CSSValueKeywords.in:
+
+ Add a 'revert-layer' keyword.
+
+ * css/parser/CSSParserIdioms.h:
+ (WebCore::isCSSWideKeyword):
+
+ Make the keyword CSS-wide.
+
+ (WebCore::isValidCustomIdentifier):
+ * style/CascadeLevel.h:
+ (WebCore::Style::operator--):
+
+ Add decrement operator.
+
+ (WebCore::Style::allCascadeLevels): Deleted.
+ * style/ElementRuleCollector.cpp:
+ (WebCore::Style::ElementRuleCollector::addElementStyleProperties):
+ (WebCore::Style::ElementRuleCollector::transferMatchedRules):
+
+ Pass the casdade layer priority so it is available when resolving the cascade.
+
+ (WebCore::Style::ElementRuleCollector::addElementInlineStyleProperties):
+
+ Add a bit indicating if the properties came from a style attribute. This is needed for correct resolution of !important with cascade layers.
+
+ * style/ElementRuleCollector.h:
+ * style/PropertyCascade.cpp:
+ (WebCore::Style::PropertyCascade::PropertyCascade):
+
+ Specify cascade levels in terms of the maximum level instead of an OptionSet of levels. This makes things simpler.
+ Make it a member.
+ Provide maximum cascade layer priority when constructing rollback cascade.
+
+ (WebCore::Style::PropertyCascade::buildCascade):
+ (WebCore::Style::PropertyCascade::setPropertyInternal):
+ (WebCore::Style::PropertyCascade::addMatch):
+
+ Ignore properties with cascade level higher than the maximum.
+
+ (WebCore::Style::PropertyCascade::addImportantMatches):
+
+ Take cascade layers into accouny when sorting important matches.
+
+ (WebCore::Style::PropertyCascade::propertyCascadeForRollback const): Deleted.
+
+ Move rollback cascades to Builder.
+
+ * style/PropertyCascade.h:
+ (WebCore::Style::PropertyCascade::maximumCascadeLevel const):
+ (WebCore::Style::PropertyCascade::maximumCascadeLayerPriority const):
+ * style/StyleBuilder.cpp:
+ (WebCore::Style::Builder::Builder):
+
+ Specify cascade levels in terms of the maximum level instead of an OptionSet of levels.
+
+ (WebCore::Style::Builder::applyCascadeProperty):
+ (WebCore::Style::Builder::applyProperty):
+
+ Construct rollback cascade for 'revert-layer' case too. This is similar to 'revert'.
+
+ (WebCore::Style::Builder::ensureRollbackCascadeForRevert):
+ (WebCore::Style::Builder::ensureRollbackCascadeForRevertLayer):
+
+ Make the rollback cascades and store them into a HashMap.
+
+ (WebCore::Style::Builder::makeRollbackCascadeKey):
+ * style/StyleBuilder.h:
+ * style/StyleBuilderState.h:
+ * style/StyleResolver.cpp:
+ (WebCore::Style::Resolver::styleForKeyframe):
+ (WebCore::Style::Resolver::styleForPage):
+ (WebCore::Style::Resolver::applyMatchedProperties):
+
+ Adopt to the new interface.
+
2021-11-09 Tim Nguyen <[email protected]>
Re-use isCSSWideKeyword in CSSVariableParser.cpp & CSSPropertyParser.cpp
Modified: trunk/Source/WebCore/css/CSSPrimitiveValue.h (285485 => 285486)
--- trunk/Source/WebCore/css/CSSPrimitiveValue.h 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/css/CSSPrimitiveValue.h 2021-11-09 09:29:43 UTC (rev 285486)
@@ -120,6 +120,7 @@
bool isInheritValue() const { return valueID() == CSSValueInherit; }
bool isUnsetValue() const { return valueID() == CSSValueUnset; }
bool isRevertValue() const { return valueID() == CSSValueRevert; }
+ bool isRevertLayerValue() const { return valueID() == CSSValueRevertLayer; }
bool isCSSWideKeyword() const;
static Ref<CSSPrimitiveValue> createIdentifier(CSSValueID valueID) { return adoptRef(*new CSSPrimitiveValue(valueID)); }
Modified: trunk/Source/WebCore/css/CSSValue.cpp (285485 => 285486)
--- trunk/Source/WebCore/css/CSSValue.cpp 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/css/CSSValue.cpp 2021-11-09 09:29:43 UTC (rev 285486)
@@ -510,6 +510,11 @@
return is<CSSPrimitiveValue>(*this) && downcast<CSSPrimitiveValue>(*this).isRevertValue();
}
+bool CSSValue::isRevertLayerValue() const
+{
+ return is<CSSPrimitiveValue>(*this) && downcast<CSSPrimitiveValue>(*this).isRevertLayerValue();
+}
+
bool CSSValue::isCSSWideKeyword() const
{
return is<CSSPrimitiveValue>(*this) && downcast<CSSPrimitiveValue>(*this).isCSSWideKeyword();
Modified: trunk/Source/WebCore/css/CSSValue.h (285485 => 285486)
--- trunk/Source/WebCore/css/CSSValue.h 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/css/CSSValue.h 2021-11-09 09:29:43 UTC (rev 285486)
@@ -111,6 +111,7 @@
bool isInitialValue() const;
bool isUnsetValue() const;
bool isRevertValue() const;
+ bool isRevertLayerValue() const;
bool isCSSWideKeyword() const;
bool treatAsInitialValue(CSSPropertyID) const;
bool treatAsInheritedValue(CSSPropertyID) const;
Modified: trunk/Source/WebCore/css/CSSValueKeywords.in (285485 => 285486)
--- trunk/Source/WebCore/css/CSSValueKeywords.in 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/css/CSSValueKeywords.in 2021-11-09 09:29:43 UTC (rev 285486)
@@ -5,6 +5,7 @@
initial
unset
revert
+revert-layer
//
// CSS_PROP_OUTLINE_STYLE
Modified: trunk/Source/WebCore/css/parser/CSSParserIdioms.h (285485 => 285486)
--- trunk/Source/WebCore/css/parser/CSSParserIdioms.h 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/css/parser/CSSParserIdioms.h 2021-11-09 09:29:43 UTC (rev 285486)
@@ -60,12 +60,21 @@
bool isValueAllowedInMode(unsigned short, CSSParserMode);
-static inline bool isCSSWideKeyword(CSSValueID valueID)
+inline bool isCSSWideKeyword(CSSValueID valueID)
{
- return valueID == CSSValueInitial || valueID == CSSValueInherit || valueID == CSSValueUnset || valueID == CSSValueRevert;
+ switch (valueID) {
+ case CSSValueInitial:
+ case CSSValueInherit:
+ case CSSValueUnset:
+ case CSSValueRevert:
+ case CSSValueRevertLayer:
+ return true;
+ default:
+ return false;
+ };
}
-static inline bool isValidCustomIdentifier(CSSValueID valueID)
+inline bool isValidCustomIdentifier(CSSValueID valueID)
{
// "default" is obsolete as a CSS-wide keyword but is still not allowed as a custom identifier.
return !isCSSWideKeyword(valueID) && valueID != CSSValueDefault;
Modified: trunk/Source/WebCore/style/CascadeLevel.h (285485 => 285486)
--- trunk/Source/WebCore/style/CascadeLevel.h 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/style/CascadeLevel.h 2021-11-09 09:29:43 UTC (rev 285486)
@@ -36,7 +36,18 @@
Author = 1 << 2
};
-static constexpr OptionSet<CascadeLevel> allCascadeLevels() { return { CascadeLevel::UserAgent, CascadeLevel::User, CascadeLevel::Author }; }
+inline CascadeLevel& operator--(CascadeLevel& level)
+{
+ switch (level) {
+ case CascadeLevel::Author:
+ return level = CascadeLevel::User;
+ case CascadeLevel::User:
+ return level = CascadeLevel::UserAgent;
+ case CascadeLevel::UserAgent:
+ ASSERT_NOT_REACHED();
+ return level;
+ }
+}
}
}
Modified: trunk/Source/WebCore/style/ElementRuleCollector.cpp (285485 => 285486)
--- trunk/Source/WebCore/style/ElementRuleCollector.cpp 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/style/ElementRuleCollector.cpp 2021-11-09 09:29:43 UTC (rev 285486)
@@ -124,7 +124,7 @@
m_matchedRuleTransferIndex = 0;
}
-inline void ElementRuleCollector::addElementStyleProperties(const StyleProperties* propertySet, bool isCacheable)
+inline void ElementRuleCollector::addElementStyleProperties(const StyleProperties* propertySet, bool isCacheable, FromStyleAttribute fromStyleAttribute)
{
if (!propertySet || propertySet->isEmpty())
return;
@@ -132,7 +132,9 @@
if (!isCacheable)
m_result.isCacheable = false;
- addMatchedProperties({ propertySet }, DeclarationOrigin::Author);
+ auto matchedProperty = MatchedProperties { propertySet };
+ matchedProperty.fromStyleAttribute = fromStyleAttribute;
+ addMatchedProperties(WTFMove(matchedProperty), DeclarationOrigin::Author);
}
void ElementRuleCollector::collectMatchingRules(const MatchRequest& matchRequest)
@@ -203,7 +205,8 @@
&matchedRule.ruleData->styleRule().properties(),
static_cast<uint16_t>(matchedRule.ruleData->linkMatchType()),
matchedRule.ruleData->propertyAllowlist(),
- matchedRule.styleScopeOrdinal
+ matchedRule.styleScopeOrdinal,
+ matchedRule.cascadeLayerPriority
}, declarationOrigin);
}
}
@@ -560,7 +563,7 @@
if (auto* inlineStyle = downcast<StyledElement>(element()).inlineStyle()) {
// FIXME: Media control shadow trees seem to have problems with caching.
bool isInlineStyleCacheable = !inlineStyle->isMutable() && !element().isInShadowTree();
- addElementStyleProperties(inlineStyle, isInlineStyleCacheable);
+ addElementStyleProperties(inlineStyle, isInlineStyleCacheable, FromStyleAttribute::Yes);
}
if (includeSMILProperties && is<SVGElement>(element()))
Modified: trunk/Source/WebCore/style/ElementRuleCollector.h (285485 => 285486)
--- trunk/Source/WebCore/style/ElementRuleCollector.h 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/style/ElementRuleCollector.h 2021-11-09 09:29:43 UTC (rev 285486)
@@ -63,14 +63,18 @@
const RuleData* ruleData;
unsigned specificity;
ScopeOrdinal styleScopeOrdinal;
- unsigned cascadeLayerPriority;
+ CascadeLayerPriority cascadeLayerPriority;
};
+enum class FromStyleAttribute : bool { No, Yes };
+
struct MatchedProperties {
RefPtr<const StyleProperties> properties;
uint16_t linkMatchType { SelectorChecker::MatchAll };
PropertyAllowlist allowlistType { PropertyAllowlist::None };
ScopeOrdinal styleScopeOrdinal { ScopeOrdinal::Element };
+ CascadeLayerPriority cascadeLayerPriority { RuleSet::cascadeLayerPriorityForUnlayered };
+ FromStyleAttribute fromStyleAttribute { FromStyleAttribute::No };
};
struct MatchResult {
@@ -121,7 +125,7 @@
bool didMatchUncommonAttributeSelector() const { return m_didMatchUncommonAttributeSelector; }
private:
- void addElementStyleProperties(const StyleProperties*, bool isCacheable = true);
+ void addElementStyleProperties(const StyleProperties*, bool isCacheable = true, FromStyleAttribute = FromStyleAttribute::No);
void matchUARules(const RuleSet&);
Modified: trunk/Source/WebCore/style/PropertyCascade.cpp (285485 => 285486)
--- trunk/Source/WebCore/style/PropertyCascade.cpp 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/style/PropertyCascade.cpp 2021-11-09 09:29:43 UTC (rev 285486)
@@ -71,30 +71,35 @@
}
}
-PropertyCascade::PropertyCascade(const MatchResult& matchResult, OptionSet<CascadeLevel> cascadeLevels, IncludedProperties includedProperties, Direction direction)
+PropertyCascade::PropertyCascade(const MatchResult& matchResult, CascadeLevel maximumCascadeLevel, IncludedProperties includedProperties, Direction direction)
: m_matchResult(matchResult)
, m_includedProperties(includedProperties)
+ , m_maximumCascadeLevel(maximumCascadeLevel)
, m_direction(direction)
{
- buildCascade(cascadeLevels);
+ buildCascade();
}
-PropertyCascade::PropertyCascade(const PropertyCascade& parent, OptionSet<CascadeLevel> cascadeLevels)
+PropertyCascade::PropertyCascade(const PropertyCascade& parent, CascadeLevel maximumCascadeLevel, CascadeLayerPriority maximumCascadeLayerPriority)
: m_matchResult(parent.m_matchResult)
, m_includedProperties(parent.m_includedProperties)
+ , m_maximumCascadeLevel(maximumCascadeLevel)
+ , m_maximumCascadeLayerPriority(maximumCascadeLayerPriority)
, m_direction(parent.direction())
, m_directionIsUnresolved(false)
{
- buildCascade(cascadeLevels);
+ buildCascade();
}
PropertyCascade::~PropertyCascade() = default;
-void PropertyCascade::buildCascade(OptionSet<CascadeLevel> cascadeLevels)
+void PropertyCascade::buildCascade()
{
OptionSet<CascadeLevel> cascadeLevelsWithImportant;
- for (auto cascadeLevel : cascadeLevels) {
+ for (auto cascadeLevel : { CascadeLevel::UserAgent, CascadeLevel::User, CascadeLevel::Author }) {
+ if (cascadeLevel > m_maximumCascadeLevel)
+ break;
bool hasImportant = addNormalMatches(cascadeLevel);
if (hasImportant)
cascadeLevelsWithImportant.add(cascadeLevel);
@@ -113,6 +118,8 @@
property.id = id;
property.level = cascadeLevel;
property.styleScopeOrdinal = matchedProperties.styleScopeOrdinal;
+ property.cascadeLayerPriority = matchedProperties.cascadeLayerPriority;
+
if (matchedProperties.linkMatchType == SelectorChecker::MatchAll) {
property.cssValue[0] = &cssValue;
property.cssValue[SelectorChecker::MatchLink] = &cssValue;
@@ -170,6 +177,9 @@
bool PropertyCascade::addMatch(const MatchedProperties& matchedProperties, CascadeLevel cascadeLevel, bool important)
{
+ if (matchedProperties.cascadeLayerPriority > m_maximumCascadeLayerPriority && cascadeLevel == m_maximumCascadeLevel && matchedProperties.styleScopeOrdinal == ScopeOrdinal::Element)
+ return false;
+
auto& styleProperties = *matchedProperties.properties;
auto propertyAllowlist = matchedProperties.allowlistType;
bool hasImportantProperties = false;
@@ -237,12 +247,14 @@
void PropertyCascade::addImportantMatches(CascadeLevel cascadeLevel)
{
- struct IndexAndOrdinal {
+ struct ImportantMatch {
unsigned index;
ScopeOrdinal ordinal;
+ CascadeLayerPriority layerPriority;
+ FromStyleAttribute fromStyleAttribute;
};
- Vector<IndexAndOrdinal> importantMatches;
- bool hasMatchesFromOtherScopes = false;
+ Vector<ImportantMatch> importantMatches;
+ bool hasMatchesFromOtherScopesOrLayers = false;
auto& matchedDeclarations = declarationsForCascadeLevel(m_matchResult, cascadeLevel);
@@ -252,20 +264,25 @@
if (!hasImportantProperties(*matchedProperties.properties))
continue;
- importantMatches.append({ i, matchedProperties.styleScopeOrdinal });
+ importantMatches.append({ i, matchedProperties.styleScopeOrdinal, matchedProperties.cascadeLayerPriority, matchedProperties.fromStyleAttribute });
- if (matchedProperties.styleScopeOrdinal != ScopeOrdinal::Element)
- hasMatchesFromOtherScopes = true;
+ if (matchedProperties.styleScopeOrdinal != ScopeOrdinal::Element || matchedProperties.cascadeLayerPriority != RuleSet::cascadeLayerPriorityForUnlayered)
+ hasMatchesFromOtherScopesOrLayers = true;
}
if (importantMatches.isEmpty())
return;
- if (hasMatchesFromOtherScopes) {
- // For !important properties a later shadow tree wins.
+ if (hasMatchesFromOtherScopesOrLayers) {
// Match results are sorted in reverse tree context order so this is not needed for normal properties.
- std::stable_sort(importantMatches.begin(), importantMatches.end(), [] (const IndexAndOrdinal& a, const IndexAndOrdinal& b) {
- return a.ordinal < b.ordinal;
+ std::stable_sort(importantMatches.begin(), importantMatches.end(), [] (auto& a, auto& b) {
+ // For !important properties a later shadow tree wins.
+ if (a.ordinal != b.ordinal)
+ return a.ordinal < b.ordinal;
+ // Lower priority layer wins, except if style attribute is involved.
+ if (a.fromStyleAttribute != b.fromStyleAttribute)
+ return a.fromStyleAttribute == FromStyleAttribute::No;
+ return a.layerPriority > b.layerPriority;
});
}
@@ -273,30 +290,6 @@
addMatch(matchedDeclarations[match.index], cascadeLevel, true);
}
-const PropertyCascade* PropertyCascade::propertyCascadeForRollback(CascadeLevel cascadeLevel) const
-{
- switch (cascadeLevel) {
- case CascadeLevel::Author:
- if (!m_authorRollbackCascade) {
- auto cascadeLevels = OptionSet<CascadeLevel> { CascadeLevel::UserAgent, CascadeLevel::User };
- m_authorRollbackCascade = makeUnique<const PropertyCascade>(*this, cascadeLevels);
- }
- return m_authorRollbackCascade.get();
-
- case CascadeLevel::User:
- if (!m_userRollbackCascade) {
- auto cascadeLevels = OptionSet<CascadeLevel> { CascadeLevel::UserAgent };
- m_userRollbackCascade = makeUnique<const PropertyCascade>(*this, cascadeLevels);
- }
- return m_userRollbackCascade.get();
-
- case CascadeLevel::UserAgent:
- return nullptr;
- }
- ASSERT_NOT_REACHED();
- return nullptr;
-}
-
PropertyCascade::Direction PropertyCascade::resolveDirectionAndWritingMode(Direction inheritedDirection) const
{
Direction result = inheritedDirection;
Modified: trunk/Source/WebCore/style/PropertyCascade.h (285485 => 285486)
--- trunk/Source/WebCore/style/PropertyCascade.h 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/style/PropertyCascade.h 2021-11-09 09:29:43 UTC (rev 285486)
@@ -46,8 +46,8 @@
WritingMode writingMode;
};
- PropertyCascade(const MatchResult&, OptionSet<CascadeLevel>, IncludedProperties, Direction);
- PropertyCascade(const PropertyCascade&, OptionSet<CascadeLevel>);
+ PropertyCascade(const MatchResult&, CascadeLevel, IncludedProperties, Direction);
+ PropertyCascade(const PropertyCascade&, CascadeLevel, CascadeLayerPriority maximumCascadeLayerPriority = RuleSet::cascadeLayerPriorityForUnlayered);
~PropertyCascade();
@@ -55,6 +55,7 @@
CSSPropertyID id;
CascadeLevel level;
ScopeOrdinal styleScopeOrdinal;
+ CascadeLayerPriority cascadeLayerPriority;
CSSValue* cssValue[3]; // Values for link match states MatchDefault, MatchLink and MatchVisited
};
@@ -69,10 +70,11 @@
Direction direction() const;
- const PropertyCascade* propertyCascadeForRollback(CascadeLevel) const;
+ auto maximumCascadeLevel() const { return m_maximumCascadeLevel; }
+ auto maximumCascadeLayerPriority() const { return m_maximumCascadeLayerPriority; }
private:
- void buildCascade(OptionSet<CascadeLevel>);
+ void buildCascade();
bool addNormalMatches(CascadeLevel);
void addImportantMatches(CascadeLevel);
bool addMatch(const MatchedProperties&, CascadeLevel, bool important);
@@ -85,6 +87,8 @@
const MatchResult& m_matchResult;
const IncludedProperties m_includedProperties;
+ const CascadeLevel m_maximumCascadeLevel;
+ const CascadeLayerPriority m_maximumCascadeLayerPriority { RuleSet::cascadeLayerPriorityForUnlayered };
mutable Direction m_direction;
mutable bool m_directionIsUnresolved { true };
@@ -93,9 +97,6 @@
Vector<Property, 8> m_deferredProperties;
HashMap<AtomString, Property> m_customProperties;
-
- mutable std::unique_ptr<const PropertyCascade> m_authorRollbackCascade;
- mutable std::unique_ptr<const PropertyCascade> m_userRollbackCascade;
};
inline bool PropertyCascade::hasProperty(CSSPropertyID id) const
Modified: trunk/Source/WebCore/style/RuleSet.h (285485 => 285486)
--- trunk/Source/WebCore/style/RuleSet.h 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/style/RuleSet.h 2021-11-09 09:29:43 UTC (rev 285486)
@@ -43,6 +43,8 @@
class Resolver;
class RuleSet;
+using CascadeLayerPriority = uint32_t;
+
using InvalidationRuleSetVector = Vector<RefPtr<const RuleSet>, 1>;
struct DynamicMediaQueryEvaluationChanges {
@@ -103,8 +105,8 @@
bool hasShadowPseudoElementRules() const { return !m_shadowPseudoElementRules.isEmpty(); }
bool hasHostPseudoClassRulesMatchingInShadowTree() const { return m_hasHostPseudoClassRulesMatchingInShadowTree; }
- static constexpr auto cascadeLayerPriorityForUnlayered = std::numeric_limits<unsigned>::max();
- unsigned cascadeLayerPriorityFor(const RuleData&) const;
+ static constexpr auto cascadeLayerPriorityForUnlayered = std::numeric_limits<CascadeLayerPriority>::max();
+ CascadeLayerPriority cascadeLayerPriorityFor(const RuleData&) const;
private:
friend class RuleSetBuilder;
@@ -136,7 +138,7 @@
};
CascadeLayer& cascadeLayerForIdentifier(CascadeLayerIdentifier identifier) { return m_cascadeLayers[identifier - 1]; }
const CascadeLayer& cascadeLayerForIdentifier(CascadeLayerIdentifier identifier) const { return m_cascadeLayers[identifier - 1]; }
- unsigned cascadeLayerPriorityForIdentifier(CascadeLayerIdentifier) const;
+ CascadeLayerPriority cascadeLayerPriorityForIdentifier(CascadeLayerIdentifier) const;
struct DynamicMediaQueryRules {
Vector<Ref<const MediaQuerySet>> mediaQuerySets;
@@ -193,7 +195,7 @@
return tagRules->get(key);
}
-inline unsigned RuleSet::cascadeLayerPriorityForIdentifier(CascadeLayerIdentifier identifier) const
+inline CascadeLayerPriority RuleSet::cascadeLayerPriorityForIdentifier(CascadeLayerIdentifier identifier) const
{
if (!identifier)
return cascadeLayerPriorityForUnlayered;
@@ -200,7 +202,7 @@
return cascadeLayerForIdentifier(identifier).priority;
}
-inline unsigned RuleSet::cascadeLayerPriorityFor(const RuleData& ruleData) const
+inline CascadeLayerPriority RuleSet::cascadeLayerPriorityFor(const RuleData& ruleData) const
{
if (m_cascadeLayerIdentifierForRulePosition.size() <= ruleData.position())
return cascadeLayerPriorityForUnlayered;
Modified: trunk/Source/WebCore/style/StyleBuilder.cpp (285485 => 285486)
--- trunk/Source/WebCore/style/StyleBuilder.cpp 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/style/StyleBuilder.cpp 2021-11-09 09:29:43 UTC (rev 285486)
@@ -80,8 +80,8 @@
return false;
}
-Builder::Builder(RenderStyle& style, BuilderContext&& context, const MatchResult& matchResult, OptionSet<CascadeLevel> cascadeLevels, PropertyCascade::IncludedProperties includedProperties)
- : m_cascade(matchResult, cascadeLevels, includedProperties, directionFromStyle(style))
+Builder::Builder(RenderStyle& style, BuilderContext&& context, const MatchResult& matchResult, CascadeLevel cascadeLevel, PropertyCascade::IncludedProperties includedProperties)
+ : m_cascade(matchResult, cascadeLevel, includedProperties, directionFromStyle(style))
, m_state(*this, style, WTFMove(context))
{
}
@@ -121,16 +121,6 @@
ASSERT(!m_state.fontDirty());
}
-void Builder::applyPropertyValue(CSSPropertyID propertyID, CSSValue* value)
-{
- if (!value)
- return;
-
- applyProperty(propertyID, *value, SelectorChecker::MatchDefault);
-
- m_state.updateFont();
-}
-
void Builder::applyDeferredProperties()
{
for (auto& property : m_cascade.deferredProperties())
@@ -245,6 +235,7 @@
{
m_state.m_cascadeLevel = property.level;
m_state.m_styleScopeOrdinal = property.styleScopeOrdinal;
+ m_state.m_cascadeLayerPriority = property.cascadeLayerPriority;
auto applyWithLinkMatch = [&](SelectorChecker::LinkMatchMask linkMatch) {
if (property.cssValue[linkMatch]) {
@@ -295,21 +286,27 @@
bool isUnset = valueToApply->isUnsetValue() || customPropertyValueID == CSSValueUnset;
bool isRevert = valueToApply->isRevertValue() || customPropertyValueID == CSSValueRevert;
+ bool isRevertLayer = valueToApply->isRevertLayerValue() || customPropertyValueID == CSSValueRevertLayer;
- if (isRevert) {
- if (auto* rollback = m_cascade.propertyCascadeForRollback(m_state.m_cascadeLevel)) {
+ if (isRevert || isRevertLayer) {
+ auto* rollbackCascade = isRevert
+ ? ensureRollbackCascadeForRevert(m_state.m_cascadeLevel)
+ : ensureRollbackCascadeForRevertLayer(m_state.m_cascadeLevel, m_state.m_cascadeLayerPriority);
+
+ if (rollbackCascade) {
// 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.
+ // not present, then we behave like "unset." Otherwise we apply the property instead of our own.
+ SetForScope cascadeLevelScope(m_state.m_cascadeLevel, rollbackCascade->maximumCascadeLevel());
+ SetForScope cascadeLayerPriorityScope(m_state.m_cascadeLayerPriority, rollbackCascade->maximumCascadeLayerPriority());
if (customPropertyValue) {
- if (customPropertyRegistered && customPropertyRegistered->inherits && rollback->hasCustomProperty(customPropertyValue->name())) {
- auto property = rollback->customProperty(customPropertyValue->name());
+ if (customPropertyRegistered && customPropertyRegistered->inherits && rollbackCascade->hasCustomProperty(customPropertyValue->name())) {
+ auto property = rollbackCascade->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);
+ } else if (rollbackCascade->hasProperty(id)) {
+ auto& property = rollbackCascade->property(id);
if (property.cssValue[linkMatchMask])
applyProperty(property.id, *property.cssValue[linkMatchMask], linkMatchMask);
return;
@@ -373,5 +370,32 @@
return CSSParser(m_state.document()).parseValueWithVariableReferences(propertyID, value, m_state);
}
+const PropertyCascade* Builder::ensureRollbackCascadeForRevert(CascadeLevel rollbackCascadeLevel)
+{
+ if (rollbackCascadeLevel == CascadeLevel::UserAgent)
+ return nullptr;
+
+ auto key = makeRollbackCascadeKey(rollbackCascadeLevel, RuleSet::cascadeLayerPriorityForUnlayered);
+ return m_rollbackCascades.ensure(key, [&] {
+ return makeUnique<const PropertyCascade>(m_cascade, --rollbackCascadeLevel, RuleSet::cascadeLayerPriorityForUnlayered);
+ }).iterator->value.get();
}
+
+const PropertyCascade* Builder::ensureRollbackCascadeForRevertLayer(CascadeLevel cascadeLevel, CascadeLayerPriority rollbackLayerPriority)
+{
+ if (!rollbackLayerPriority)
+ return nullptr;
+
+ auto key = makeRollbackCascadeKey(cascadeLevel, rollbackLayerPriority);
+ return m_rollbackCascades.ensure(key, [&] {
+ return makeUnique<const PropertyCascade>(m_cascade, cascadeLevel, rollbackLayerPriority - 1);
+ }).iterator->value.get();
}
+
+auto Builder::makeRollbackCascadeKey(CascadeLevel cascadeLevel, CascadeLayerPriority cascadeLayerPriority) -> RollbackCascadeKey
+{
+ return { static_cast<unsigned>(cascadeLevel), static_cast<unsigned>(cascadeLayerPriority) };
+}
+
+}
+}
Modified: trunk/Source/WebCore/style/StyleBuilder.h (285485 => 285486)
--- trunk/Source/WebCore/style/StyleBuilder.h 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/style/StyleBuilder.h 2021-11-09 09:29:43 UTC (rev 285486)
@@ -35,7 +35,7 @@
class Builder {
WTF_MAKE_FAST_ALLOCATED;
public:
- Builder(RenderStyle&, BuilderContext&&, const MatchResult&, OptionSet<CascadeLevel>, PropertyCascade::IncludedProperties = PropertyCascade::IncludedProperties::All);
+ Builder(RenderStyle&, BuilderContext&&, const MatchResult&, CascadeLevel, PropertyCascade::IncludedProperties = PropertyCascade::IncludedProperties::All);
~Builder();
void applyAllProperties();
@@ -45,8 +45,6 @@
void applyProperty(CSSPropertyID propertyID) { applyProperties(propertyID, propertyID); }
void applyCustomProperty(const String& name);
- void applyPropertyValue(CSSPropertyID, CSSValue*);
-
BuilderState& state() { return m_state; }
private:
@@ -63,7 +61,16 @@
Ref<CSSValue> resolveValue(CSSPropertyID, CSSValue&);
RefPtr<CSSValue> resolvedVariableValue(CSSPropertyID, const CSSValue&);
+ const PropertyCascade* ensureRollbackCascadeForRevert(CascadeLevel);
+ const PropertyCascade* ensureRollbackCascadeForRevertLayer(CascadeLevel, CascadeLayerPriority);
+
+ using RollbackCascadeKey = std::pair<unsigned, unsigned>;
+ RollbackCascadeKey makeRollbackCascadeKey(CascadeLevel, CascadeLayerPriority);
+
const PropertyCascade m_cascade;
+ // Rollback cascades are build on demand to resolve 'revert' and 'revert-layer' keywords.
+ HashMap<RollbackCascadeKey, std::unique_ptr<const PropertyCascade>> m_rollbackCascades;
+
BuilderState m_state;
};
Modified: trunk/Source/WebCore/style/StyleBuilderState.h (285485 => 285486)
--- trunk/Source/WebCore/style/StyleBuilderState.h 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/style/StyleBuilderState.h 2021-11-09 09:29:43 UTC (rev 285486)
@@ -29,6 +29,7 @@
#include "CSSToStyleMap.h"
#include "CascadeLevel.h"
#include "RenderStyle.h"
+#include "RuleSet.h"
#include "SelectorChecker.h"
#include <wtf/Bitmap.h>
@@ -136,6 +137,7 @@
CascadeLevel m_cascadeLevel { };
ScopeOrdinal m_styleScopeOrdinal { };
+ CascadeLayerPriority m_cascadeLayerPriority { };
SelectorChecker::LinkMatchMask m_linkMatch { };
bool m_fontDirty { false };
Modified: trunk/Source/WebCore/style/StyleResolver.cpp (285485 => 285486)
--- trunk/Source/WebCore/style/StyleResolver.cpp 2021-11-09 08:37:06 UTC (rev 285485)
+++ trunk/Source/WebCore/style/StyleResolver.cpp 2021-11-09 09:29:43 UTC (rev 285486)
@@ -283,7 +283,7 @@
state.setStyle(RenderStyle::clonePtr(*elementStyle));
state.setParentStyle(RenderStyle::clonePtr(context.parentStyle ? *context.parentStyle : *elementStyle));
- Builder builder(*state.style(), builderContext(state), result, { CascadeLevel::Author });
+ Builder builder(*state.style(), builderContext(state), result, CascadeLevel::Author);
builder.applyAllProperties();
Adjuster adjuster(document(), *state.parentStyle(), nullptr, nullptr);
@@ -436,7 +436,7 @@
auto& result = collector.matchResult();
- Builder builder(*state.style(), builderContext(state), result, { CascadeLevel::Author });
+ Builder builder(*state.style(), builderContext(state), result, CascadeLevel::Author);
builder.applyAllProperties();
// Now return the style.
@@ -555,13 +555,13 @@
// 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);
- Builder builder(*userAgentStyle, builderContext(state), matchResult, { CascadeLevel::UserAgent });
+ Builder builder(*userAgentStyle, builderContext(state), matchResult, CascadeLevel::UserAgent);
builder.applyAllProperties();
state.setUserAgentAppearanceStyle(WTFMove(userAgentStyle));
}
- Builder builder(*state.style(), builderContext(state), matchResult, allCascadeLevels(), includedProperties);
+ Builder builder(*state.style(), builderContext(state), matchResult, CascadeLevel::Author, includedProperties);
// High priority properties may affect resolution of other properties (they are mostly font related).
builder.applyHighPriorityProperties();