Skip to main content

css_ast/selector/
functional_pseudo_element.rs

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	/// <https://drafts.csswg.org/css-highlight-api/#custom-highlight-pseudo>
14	Highlight(HighlightPseudoElement),
15	/// <https://drafts.csswg.org/css-shadow-parts/#part>
16	Part(PartPseudoElement<'a>),
17	/// <https://drafts.csswg.org/css-forms-1/#picker-pseudo>
18	Picker(PickerPseudoElement),
19	/// <https://drafts.csswg.org/css-scoping/#slotted-pseudo>
20	Slotted(SlottedPseudoElement<'a>),
21	/// <https://drafts.csswg.org/css-view-transitions-2/#view-transition-pseudo>
22	/// <https://drafts.csswg.org/css-view-transitions-2/#::view-transition-group>
23	ViewTransitionGroup(ViewTransitionGroupPseudoElement<'a>),
24	/// <https://drafts.csswg.org/css-view-transitions-2/#::view-transition-image-pair>
25	ViewTransitionImagePair(ViewTransitionImagePairPseudoElement<'a>),
26	/// <https://drafts.csswg.org/css-view-transitions-2/#::view-transition-new>
27	ViewTransitionNew(ViewTransitionNewPseudoElement<'a>),
28	/// <https://drafts.csswg.org/css-view-transitions-2/#::view-transition-old>
29	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}