CSS revert-rule keyword implementation
cdf8247
Source/WebCore/style/PropertyCascade.cpp
+PropertyCascade::PropertyCascade(const PropertyCascade& parent, RevertRuleTag)
+ : m_matchResult(parent.m_matchResult)
+ , m_includedProperties(normalProperties())
+ , m_maximumOrigin(parent.m_maximumOrigin)
+ , m_rollbackScope(parent.m_rollbackScope)
+ , m_maximumCascadeLayerPriorityForRollback(parent.m_maximumCascadeLayerPriorityForRollback)
+ , m_ruleRollbackDepth(parent.m_ruleRollbackDepth + 1)
+ , m_animationLayer(parent.m_animationLayer)
+ , m_positionTryFallbackProperties(parent.m_positionTryFallbackProperties)
+{
+ buildCascade();
+}
+void PropertyCascade::setDelayingForRuleRollback(CSSPropertyID propertyID, CSSValue& cssValue, const MatchedProperties& matchedProperties, Origin origin)
+{
+ ASSERT(m_ruleRollbackDepth);
+ auto key = [&] -> std::pair<unsigned, AtomString> {
+ if (propertyID == CSSPropertyCustom)
+ return { propertyID, downcast<CSSCustomPropertyValue>(cssValue).name() };
+ return { propertyID, emptyAtom() };
+ }();
+ auto& delayedValues = m_delayedRollbackProperties.ensure(key, [&] {
+ return Deque<DelayedRollbackProperty>();
+ }).iterator->value;
+ delayedValues.prepend(DelayedRollbackProperty { cssValue, matchedProperties, origin });
CSS cascade 알고리즘은 특정 속성에 어떤 규칙의 값이 최종적으로 적용될지를 결정합니다. WebKit에서는 이 과정을 PropertyCascade로 구현하며, 매칭된 규칙들을 수집한 뒤 최종 값을 결정합니다.
기존에도 유사한 keyword가 존재했습니다. revert는 user-agent origin으로, revert-layer는 이전 cascade layer로 되돌리는 방식입니다. 이번에 추가된 revert-rule은 CSS Cascading Level 5 명세의 새로운 keyword로, 규칙 단위로 동작합니다. 현재 규칙의 해당 속성 기여를 건너뛰고, cascade 순서상 바로 아래 규칙이 결정한 값으로 내려가는 방식입니다. 구현을 위해서는 현재 규칙이 없는 상태의 cascade를 나타내는 shadow "rollback cascade"를 별도로 구성하고, 속성을 적용하는 시점에 그 cascade의 값을 사용해야 합니다.
Cascade order (author origin, same layer):
Rule A: color: red;
Rule B: color: blue; ← value that revert-rule resolves to
Rule C: color: revert-rule; ← skip Rule C's contribution
StyleBuilder resolution:
applyProperty(color)
└─ value == revert-rule?
└─ ensureRollbackCascadeForRevertRule()
└─ PropertyCascade(parent, RevertRuleTag{})
m_ruleRollbackDepth = parent.m_ruleRollbackDepth + 1
└─ addMatch: defers values into per-property Deque
until rollback depth is satisfied
└─ apply color from rollback cascade → "blue"
구현 내용은 크게 세 가지입니다. 먼저 m_ruleRollbackDepth를 증가시키는 새로운 PropertyCascade 생성자가 추가되었습니다. 다음으로 (propertyID, customPropertyName) 쌍을 key로 사용하는 per-property Deque에 값을 유예하는 setDelayingForRuleRollback 메서드가 추가되었습니다. 마지막으로 StyleBuilder에 rollback cascade를 필요 시점에 구성하는 ensureRollbackCascadeForRevertRule이 추가되었습니다.
Significance
새로운 CSS keyword가 추가됨으로써 parsing surface가 넓어지고, cascade 결정 과정에 새로운 code path가 생겨났습니다. custom property, !important, CSS nesting, keyframe animation, container query와의 상호작용도 새로 발생하는데, 이 기능이 첫 번째 WPT suite를 막 통과한 시점임을 고려하면 아직 충분히 검증되지 않은 영역입니다.
Audit directions
Aaa Aa Aaa Aa a Aaaaa
Aa Aaa Aaaaaaaaaaaaaa Aa Aaa Aaaaaa Aaaa Aa Aaaaaaaaaaaaaa Aaaa Aaaa Aa Aaaaaaaaaaaaaa Aaaa Aaaaa Aaaa Aa Aaa Aaaa Aaaaaa Aa Aaaaaaaaaaaa Aaaaaaaa Aaaaaaa Aaaaa Aaa Aaaa Aaa Aaaaaaaaaaa Aaaa Aaa Aaa Aa Aaa Aaaa Aaaaa
Aaaaaaaaaaaaaa Aaaaa Aaaaaaa Aaaaaaaaa Aaa Aaaaaaaaaaaaaa Aaaa Aa Aaaaaaa Aaa Aaaa Aaa Aaaaaa Aaaa Aaaaa Aaaa Aaaaaaaa Aaaaaaaa Aaa a Aaaaaaaaa Aaa Aaaaaa Aaa Aaaa Aaaa Aaaa
Aaaaaa Aaaaaaaaa Aaaaaaa Aa Aaa Aa Aaaaaaa Aa Aaa Aa Aaaaaa Aaaaaaaaaaaaaa Aaa Aaaaaa Aaaaaa Aaaaaaaa Aaa Aaaa Aaaa Aa Aaaa Aaaaa
Aa Aaaaaaaa Aaaaaa Aaaaa Aaaaaa Aaaaaaa Aaaaaaaa Aaaaaa Aa Aa Aa Aaaa Aaaaa Aaa Aaaaa Aaaa Aaa Aaaa Aaaaa
Aaaaa Aaa Aaaaaaaaa Aaaa Aa Aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa Aa Aaaaaaaaa Aaaa Aa Aa Aaa Aaa Aaaa Aaaa Aaaaaa
🔒New cascade resolution code paths and edge cases in rollback depth tracking, custom property deferral, and cache key correctness are worth security investigation.
더 확인하려면 구독해 주세요