1use super::prelude::*;
2use crate::selector::ForgivingSelector;
3use css_parse::Box;
4
5#[node]
15#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
16#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
17#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
18#[cfg_attr(feature = "css_feature_data", derive(::csskit_derives::ToCSSFeature), css_feature("css.at-rules.scope"))]
19#[derive(csskit_derives::NodeWithMetadata)]
20#[metadata(node_kinds = AtRule, used_at_rules = Scope)]
21pub struct ScopeRule<'a> {
22 #[cfg_attr(feature = "visitable", visit(skip))]
23 #[atom(CssAtomSet::Scope)]
24 pub name: T![AtKeyword],
25 #[metadata(prelude)]
26 pub start: Option<Box<'a, ScopeStart<'a>>>,
27 #[metadata(prelude)]
28 pub end: Option<Box<'a, ScopeEnd<'a>>>,
29 #[metadata(block)]
30 pub block: ScopeRuleBlock<'a>,
31}
32
33#[node]
34#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
35#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
36#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable))]
37#[derive(csskit_derives::NodeWithMetadata)]
38pub struct ScopeStart<'a>(
39 #[cfg_attr(feature = "visitable", visit(skip))]
40 #[semantic_eq(skip)]
41 pub T!['('],
42 pub Option<ForgivingSelector<'a>>,
43 #[cfg_attr(feature = "visitable", visit(skip))]
44 #[semantic_eq(skip)]
45 pub T![')'],
46);
47
48#[node]
49#[derive(Parse, Peek, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
50#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
51#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable))]
52#[derive(csskit_derives::NodeWithMetadata)]
53pub struct ScopeEnd<'a>(
54 #[cfg_attr(feature = "visitable", visit(skip))]
55 #[atom(CssAtomSet::To)]
56 pub T![Ident],
57 #[cfg_attr(feature = "visitable", visit(skip))]
58 #[semantic_eq(skip)]
59 pub T!['('],
60 pub Option<ForgivingSelector<'a>>,
61 #[cfg_attr(feature = "visitable", visit(skip))]
62 #[semantic_eq(skip)]
63 pub T![')'],
64);
65
66#[node]
67#[derive(Parse, ToCursors, ToSpan, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
68#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
69#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable))]
70#[derive(csskit_derives::NodeWithMetadata)]
71pub struct ScopeRuleBlock<'a>(pub Block<'a, StyleValue<'a>, Rule<'a>, CssMetadata>);
72
73#[cfg(test)]
74mod tests {
75 use super::*;
76 use crate::CssAtomSet;
77 use css_parse::assert_parse;
78
79 #[test]
80 fn test_writes() {
81 assert_parse!(CssAtomSet::ATOMS, ScopeRule, "@scope{}");
82 assert_parse!(CssAtomSet::ATOMS, ScopeRule, "@scope(.card){}");
83 assert_parse!(CssAtomSet::ATOMS, ScopeRule, "@scope(.card) to (.content){}");
84 assert_parse!(CssAtomSet::ATOMS, ScopeRule, "@scope to (.content){}");
85 assert_parse!(CssAtomSet::ATOMS, ScopeRule, "@scope(.card,.tile) to (.content>img){}");
86 assert_parse!(CssAtomSet::ATOMS, ScopeRule, "@scope(.card){color:black}");
87 assert_parse!(CssAtomSet::ATOMS, ScopeRule, "@scope(.card){img{color:black}}");
88 assert_parse!(CssAtomSet::ATOMS, ScopeRule, "@scope(){}");
89 assert_parse!(CssAtomSet::ATOMS, ScopeRule, "@scope{img{color:black}}");
90 }
91}