1use super::prelude::*;
2use css_parse::Vec;
3
4use super::CompoundSelector;
5
6#[node]
7#[derive(ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
8#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
9#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
10#[derive(csskit_derives::NodeWithMetadata)]
11#[cfg_attr(feature = "css_feature_data", derive(::csskit_derives::ToCSSFeature), css_feature("css.selectors"))]
12pub enum FunctionalPseudoElement<'a> {
13 Highlight(HighlightPseudoElement),
15 Part(PartPseudoElement<'a>),
17 Picker(PickerPseudoElement),
19 Slotted(SlottedPseudoElement<'a>),
21 ViewTransitionGroup(ViewTransitionGroupPseudoElement<'a>),
24 ViewTransitionImagePair(ViewTransitionImagePairPseudoElement<'a>),
26 ViewTransitionNew(ViewTransitionNewPseudoElement<'a>),
28 ViewTransitionOld(ViewTransitionOldPseudoElement<'a>),
30}
31
32impl<'a> Peek<'a> for FunctionalPseudoElement<'a> {
33 const PEEK_KINDSET: KindSet = KindSet::new(&[Kind::Colon]);
34
35 #[inline(always)]
36 fn peek<I>(p: &Parser<'a, I>, _: css_lexer::Cursor) -> bool
37 where
38 I: Iterator<Item = Cursor> + Clone,
39 {
40 p.peek::<T![::]>() && p.peek_n(3) == Kind::Function
41 }
42}
43
44impl<'a> Parse<'a> for FunctionalPseudoElement<'a> {
45 fn parse<I>(p: &mut Parser<'a, I>) -> ParserResult<Self>
46 where
47 I: Iterator<Item = Cursor> + Clone,
48 {
49 match p.to_atom::<CssAtomSet>(p.peek_n(3)) {
50 CssAtomSet::Highlight => p.parse::<HighlightPseudoElement>().map(Self::Highlight),
51 CssAtomSet::Part => p.parse::<PartPseudoElement>().map(Self::Part),
52 CssAtomSet::Picker => p.parse::<PickerPseudoElement>().map(Self::Picker),
53 CssAtomSet::Slotted => p.parse::<SlottedPseudoElement>().map(Self::Slotted),
54 CssAtomSet::ViewTransitionGroup => {
55 p.parse::<ViewTransitionGroupPseudoElement>().map(Self::ViewTransitionGroup)
56 }
57 CssAtomSet::ViewTransitionImagePair => {
58 p.parse::<ViewTransitionImagePairPseudoElement>().map(Self::ViewTransitionImagePair)
59 }
60 CssAtomSet::ViewTransitionNew => p.parse::<ViewTransitionNewPseudoElement>().map(Self::ViewTransitionNew),
61 CssAtomSet::ViewTransitionOld => p.parse::<ViewTransitionOldPseudoElement>().map(Self::ViewTransitionOld),
62 _ => Err(Diagnostic::new(p.next(), Diagnostic::unexpected_pseudo_element))?,
63 }
64 }
65}
66
67#[node]
68#[derive(Parse, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
69#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
70#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
71#[derive(csskit_derives::NodeWithMetadata)]
72pub struct HighlightPseudoElement {
73 #[semantic_eq(skip)]
74 pub colons: T![::],
75 #[atom(CssAtomSet::Highlight)]
76 pub function: T![Function],
77 pub value: T![Ident],
78 #[semantic_eq(skip)]
79 pub close: T![')'],
80}
81
82#[node]
83#[derive(Parse, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
84#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
85#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit)]
86#[derive(csskit_derives::NodeWithMetadata)]
87pub struct SlottedPseudoElement<'a> {
88 #[cfg_attr(feature = "visitable", visit(skip))]
89 #[semantic_eq(skip)]
90 pub colons: T![::],
91 #[cfg_attr(feature = "visitable", visit(skip))]
92 #[atom(CssAtomSet::Slotted)]
93 pub function: T![Function],
94 pub value: CompoundSelector<'a>,
95 #[cfg_attr(feature = "visitable", visit(skip))]
96 #[semantic_eq(skip)]
97 pub close: Option<T![')']>,
98}
99
100#[node]
101#[derive(Parse, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
102#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
103#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
104#[derive(csskit_derives::NodeWithMetadata)]
105pub struct PartPseudoElement<'a> {
106 #[semantic_eq(skip)]
107 pub colons: T![::],
108 #[atom(CssAtomSet::Part)]
109 pub function: T![Function],
110 pub value: Vec<'a, T![Ident]>,
111 #[semantic_eq(skip)]
112 pub close: Option<T![')']>,
113}
114
115#[node]
116#[derive(Parse, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
117#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
118#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
119#[derive(csskit_derives::NodeWithMetadata)]
120pub struct PickerPseudoElement {
121 #[semantic_eq(skip)]
122 pub colons: T![::],
123 #[atom(CssAtomSet::Picker)]
124 pub function: T![Function],
125 pub value: T![Ident],
126 #[semantic_eq(skip)]
127 pub close: Option<T![')']>,
128}
129
130#[node]
131#[derive(Parse, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
132#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
133#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
134#[derive(csskit_derives::NodeWithMetadata)]
135pub struct ViewTransitionGroupPseudoElement<'a> {
136 #[semantic_eq(skip)]
137 pub colons: T![::],
138 #[atom(CssAtomSet::ViewTransitionGroup)]
139 pub function: T![Function],
140 pub value: PtNameAndClassSelector<'a>,
141 #[semantic_eq(skip)]
142 pub close: Option<T![')']>,
143}
144
145#[node]
146#[derive(Parse, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
147#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
148#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
149#[derive(csskit_derives::NodeWithMetadata)]
150pub struct ViewTransitionImagePairPseudoElement<'a> {
151 #[semantic_eq(skip)]
152 pub colons: T![::],
153 #[atom(CssAtomSet::ViewTransitionImagePair)]
154 pub function: T![Function],
155 pub value: PtNameAndClassSelector<'a>,
156 #[semantic_eq(skip)]
157 pub close: Option<T![')']>,
158}
159
160#[node]
161#[derive(Parse, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
162#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
163#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
164#[derive(csskit_derives::NodeWithMetadata)]
165pub struct ViewTransitionNewPseudoElement<'a> {
166 #[semantic_eq(skip)]
167 pub colons: T![::],
168 #[atom(CssAtomSet::ViewTransitionNew)]
169 pub function: T![Function],
170 pub value: PtNameAndClassSelector<'a>,
171 #[semantic_eq(skip)]
172 pub close: Option<T![')']>,
173}
174
175#[node]
176#[derive(Parse, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
177#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
178#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
179#[derive(csskit_derives::NodeWithMetadata)]
180pub struct ViewTransitionOldPseudoElement<'a> {
181 #[semantic_eq(skip)]
182 pub colons: T![::],
183 #[atom(CssAtomSet::ViewTransitionOld)]
184 pub function: T![Function],
185 pub value: PtNameAndClassSelector<'a>,
186 #[semantic_eq(skip)]
187 pub close: Option<T![')']>,
188}
189
190#[node]
191#[derive(Parse, ToSpan, ToCursors, SemanticEq, Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
192#[cfg_attr(feature = "serde", derive(serde::Serialize), serde())]
193#[cfg_attr(feature = "visitable", derive(csskit_derives::Visitable), visit(self))]
194#[derive(csskit_derives::NodeWithMetadata)]
195pub enum PtNameAndClassSelector<'a> {
196 Wildcard(#[semantic_eq(skip)] T![*]),
197 Named(T![Ident], Vec<'a, (T![.], T![Ident])>),
198 Classes(Vec<'a, (T![.], T![Ident])>),
199}