[CSS Cascade Layers] Initial support
https://bugs.webkit.org/show_bug.cgi?id=229542

Reviewed by Simon Fraser.

LayoutTests/imported/w3c:

* web-platform-tests/css/css-cascade/layer-basic-expected.txt:

Source/WebCore:

https://www.w3.org/TR/css-cascade-5/#cascade-layers

This patch adds initial support for @layer rules, including both the block and the statement syntax.
No support for @import or CSSOM yet but basic functionality mostly works.

The feature is disabled by default.

* css/StyleRule.cpp:
(WebCore::StyleRuleBase::destroy):
(WebCore::StyleRuleBase::copy const):
(WebCore::StyleRuleBase::createCSSOMWrapper const):
(WebCore::StyleRuleLayer::StyleRuleLayer):
(WebCore::m_nameVariant):
(WebCore::StyleRuleLayer::create):
* css/StyleRule.h:
(WebCore::StyleRuleBase::isGroupRule const):

Add support for casting to StyleRuleGroup.

(WebCore::StyleRuleBase::isLayerRule const):
(isType):
* css/StyleRuleType.h:

Add subclass for layer.

* css/StyleSheetContents.cpp:
(WebCore::traverseRulesInVector):
(WebCore::StyleSheetContents::traverseSubresources const):

Traversal support. Also cover other missing group rules.

* css/parser/CSSAtRuleID.cpp:
(WebCore::cssAtRuleID):
* css/parser/CSSAtRuleID.h:
* css/parser/CSSParserContext.cpp:

Enable bit.

(WebCore::operator==):
(WebCore::add):
* css/parser/CSSParserContext.h:
* css/parser/CSSParserImpl.cpp:
(WebCore::CSSParserImpl::consumeAtRule):
(WebCore::CSSParserImpl::consumeLayerRule):

Parsing support.

* css/parser/CSSParserImpl.h:
* style/ElementRuleCollector.cpp:
(WebCore::Style::ElementRuleCollector::addMatchedRule):
(WebCore::Style::ElementRuleCollector::collectMatchingRulesForList):

Save the layer order to MatchResult.

(WebCore::Style::compareRules):

Layer order has higher priority than specificity but lower than scope.

* style/ElementRuleCollector.h:
* style/RuleSet.cpp:
(WebCore::Style::RuleSet::addRule):
(WebCore::Style::RuleSet::addChildRules):
(WebCore::Style::RuleSet::pushCascadeLayer):
(WebCore::Style::RuleSet::popCascadeLayer):

Compute layer order when adding the rules to RuleSet.

* style/RuleSet.h:
(WebCore::Style::RuleSet::cascadeLayerOrderFor const):

Resolved order is kept in a side vector to avoid bloating RuleSet. The vector is initialized
only if cascade layers are being used.

Source/WTF:

* Scripts/Preferences/WebPreferencesExperimental.yaml:


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@281701 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/Source/WebCore/css/StyleRule.cpp b/Source/WebCore/css/StyleRule.cpp
index 8cbdfb2..4b15c09 100644
--- a/Source/WebCore/css/StyleRule.cpp
+++ b/Source/WebCore/css/StyleRule.cpp
@@ -94,6 +94,9 @@
     case StyleRuleType::CounterStyle:
         delete downcast<StyleRuleCounterStyle>(this);
         return;
+    case StyleRuleType::Layer:
+        delete downcast<StyleRuleLayer>(this);
+        return;
     case StyleRuleType::Unknown:
         ASSERT_NOT_REACHED();
         return;
@@ -118,6 +121,8 @@
         return downcast<StyleRuleKeyframes>(*this).copy();
     case StyleRuleType::CounterStyle:
         return downcast<StyleRuleCounterStyle>(*this).copy();
+    case StyleRuleType::Layer:
+        return downcast<StyleRuleLayer>(*this).copy();
     case StyleRuleType::Import:
     case StyleRuleType::Namespace:
         // FIXME: Copy import and namespace rules.
@@ -162,6 +167,8 @@
     case StyleRuleType::CounterStyle:
         rule = CSSCounterStyleRule::create(downcast<StyleRuleCounterStyle>(self), parentSheet);
         break;
+    case StyleRuleType::Layer:
+        // FIXME: Implement.
     case StyleRuleType::Unknown:
     case StyleRuleType::Charset:
     case StyleRuleType::Keyframe:
@@ -431,6 +438,7 @@
 {
 }
 
+
 Ref<StyleRuleSupports> StyleRuleSupports::create(const String& conditionText, bool conditionIsSupported, Vector<RefPtr<StyleRuleBase>>&& rules)
 {
     return adoptRef(*new StyleRuleSupports(conditionText, conditionIsSupported, WTFMove(rules)));
@@ -441,6 +449,45 @@
     return adoptRef(*new StyleRuleSupports(conditionText, conditionIsSupported, WTFMove(rules)));
 }
 
+StyleRuleLayer::StyleRuleLayer(Vector<CascadeLayerName>&& nameList)
+    : StyleRuleGroup(StyleRuleType::Layer, Vector<RefPtr<StyleRuleBase>> { })
+    , m_nameVariant(WTFMove(nameList))
+{
+}
+
+StyleRuleLayer::StyleRuleLayer(CascadeLayerName&& name, Vector<RefPtr<StyleRuleBase>>&& rules)
+    : StyleRuleGroup(StyleRuleType::Layer, WTFMove(rules))
+    , m_nameVariant(WTFMove(name))
+{
+}
+
+StyleRuleLayer::StyleRuleLayer(CascadeLayerName&& name, std::unique_ptr<DeferredStyleGroupRuleList>&& rules)
+    : StyleRuleGroup(StyleRuleType::Layer, WTFMove(rules))
+    , m_nameVariant(WTFMove(name))
+{
+}
+
+StyleRuleLayer::StyleRuleLayer(const StyleRuleLayer& other)
+    : StyleRuleGroup(other)
+    , m_nameVariant(other.m_nameVariant)
+{
+}
+
+Ref<StyleRuleLayer> StyleRuleLayer::create(Vector<CascadeLayerName>&& nameList)
+{
+    return adoptRef(*new StyleRuleLayer(WTFMove(nameList)));
+}
+
+Ref<StyleRuleLayer> StyleRuleLayer::create(CascadeLayerName&& name, Vector<RefPtr<StyleRuleBase>>&& rules)
+{
+    return adoptRef(*new StyleRuleLayer(WTFMove(name), WTFMove(rules)));
+}
+
+Ref<StyleRuleLayer> StyleRuleLayer::create(CascadeLayerName&& name, std::unique_ptr<DeferredStyleGroupRuleList>&& rules)
+{
+    return adoptRef(*new StyleRuleLayer(WTFMove(name), WTFMove(rules)));
+}
+
 StyleRuleCharset::StyleRuleCharset()
     : StyleRuleBase(StyleRuleType::Charset)
 {