swc_css_ast/
selector.rs

1use is_macro::Is;
2use string_enum::StringEnum;
3use swc_atoms::Atom;
4use swc_common::{ast_node, util::take::Take, EqIgnoreSpan, Span};
5
6use crate::{Delimiter, Ident, ListOfComponentValues, Str, TokenAndSpan};
7
8#[ast_node("SelectorList")]
9#[derive(Eq, Hash, EqIgnoreSpan)]
10pub struct SelectorList {
11    pub span: Span,
12    pub children: Vec<ComplexSelector>,
13}
14
15impl Take for SelectorList {
16    fn dummy() -> Self {
17        Self {
18            span: Take::dummy(),
19            children: Take::dummy(),
20        }
21    }
22}
23
24#[ast_node("SelectorList")]
25#[derive(Eq, Hash, EqIgnoreSpan)]
26pub struct ForgivingSelectorList {
27    pub span: Span,
28    pub children: Vec<ForgivingComplexSelector>,
29}
30
31#[ast_node(no_unknown)]
32#[derive(Eq, Hash, Is, EqIgnoreSpan)]
33pub enum ForgivingComplexSelector {
34    #[tag("ComplexSelector")]
35    ComplexSelector(ComplexSelector),
36    #[tag("ListOfComponentValues")]
37    ListOfComponentValues(ListOfComponentValues),
38}
39
40#[ast_node("CompoundSelectorList")]
41#[derive(Eq, Hash, EqIgnoreSpan)]
42pub struct CompoundSelectorList {
43    pub span: Span,
44    pub children: Vec<CompoundSelector>,
45}
46
47#[ast_node("RelativeSelectorList")]
48#[derive(Eq, Hash, EqIgnoreSpan)]
49pub struct RelativeSelectorList {
50    pub span: Span,
51    pub children: Vec<RelativeSelector>,
52}
53
54#[ast_node("ForgivingRelativeSelectorList")]
55#[derive(Eq, Hash, EqIgnoreSpan)]
56pub struct ForgivingRelativeSelectorList {
57    pub span: Span,
58    pub children: Vec<ForgivingRelativeSelector>,
59}
60
61#[ast_node(no_unknown)]
62#[derive(Eq, Hash, Is, EqIgnoreSpan)]
63pub enum ForgivingRelativeSelector {
64    #[tag("RelativeSelector")]
65    RelativeSelector(RelativeSelector),
66    #[tag("ListOfComponentValues")]
67    ListOfComponentValues(ListOfComponentValues),
68}
69
70#[ast_node("ComplexSelector")]
71#[derive(Eq, Hash, EqIgnoreSpan)]
72pub struct ComplexSelector {
73    pub span: Span,
74    pub children: Vec<ComplexSelectorChildren>,
75}
76
77impl Take for ComplexSelector {
78    fn dummy() -> Self {
79        Self {
80            span: Take::dummy(),
81            children: Take::dummy(),
82        }
83    }
84}
85
86#[ast_node(no_unknown)]
87#[derive(Eq, Hash, Is, EqIgnoreSpan)]
88pub enum ComplexSelectorChildren {
89    #[tag("CompoundSelector")]
90    CompoundSelector(CompoundSelector),
91    #[tag("Combinator")]
92    Combinator(Combinator),
93}
94
95#[ast_node("RelativeSelector")]
96#[derive(Eq, Hash, EqIgnoreSpan)]
97pub struct RelativeSelector {
98    pub span: Span,
99    #[cfg_attr(
100        feature = "encoding-impl",
101        encoding(with = "cbor4ii::core::types::Maybe")
102    )]
103    pub combinator: Option<Combinator>,
104    pub selector: ComplexSelector,
105}
106
107/// e.g. `foo.c1.c2`
108#[ast_node("CompoundSelector")]
109#[derive(Eq, Hash, EqIgnoreSpan)]
110pub struct CompoundSelector {
111    pub span: Span,
112    /// "&"
113    #[cfg_attr(
114        feature = "encoding-impl",
115        encoding(with = "cbor4ii::core::types::Maybe")
116    )]
117    pub nesting_selector: Option<NestingSelector>,
118    #[cfg_attr(
119        feature = "encoding-impl",
120        encoding(with = "cbor4ii::core::types::Maybe")
121    )]
122    pub type_selector: Option<Box<TypeSelector>>,
123    pub subclass_selectors: Vec<SubclassSelector>,
124}
125
126#[ast_node("Combinator")]
127#[derive(Eq, Hash, EqIgnoreSpan)]
128pub struct Combinator {
129    pub span: Span,
130    pub value: CombinatorValue,
131}
132
133#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Is, EqIgnoreSpan)]
134#[cfg_attr(
135    feature = "rkyv",
136    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
137)]
138#[cfg_attr(
139    feature = "rkyv",
140    rkyv(serialize_bounds(__S: rkyv::ser::Writer + rkyv::ser::Allocator,
141        __S::Error: rkyv::rancor::Source))
142)]
143#[cfg_attr(feature = "rkyv", derive(bytecheck::CheckBytes))]
144#[cfg_attr(feature = "rkyv", repr(u32))]
145#[cfg_attr(
146    feature = "encoding-impl",
147    derive(::swc_common::Encode, ::swc_common::Decode)
148)]
149pub enum CombinatorValue {
150    /// ` `
151    Descendant,
152
153    /// `+`
154    NextSibling,
155
156    /// `>`
157    Child,
158
159    /// `~`
160    LaterSibling,
161
162    /// `||`
163    Column,
164}
165
166#[ast_node("NestingSelector")]
167#[derive(Eq, Hash, EqIgnoreSpan)]
168pub struct NestingSelector {
169    pub span: Span,
170}
171
172#[ast_node(no_unknown)]
173#[derive(Eq, Hash, Is, EqIgnoreSpan)]
174pub enum TypeSelector {
175    #[tag("TagNameSelector")]
176    TagName(TagNameSelector),
177    #[tag("UniversalSelector")]
178    Universal(UniversalSelector),
179}
180
181#[ast_node("TagNameSelector")]
182#[derive(Eq, Hash, EqIgnoreSpan)]
183pub struct TagNameSelector {
184    pub span: Span,
185    pub name: WqName,
186}
187
188#[ast_node("UniversalSelector")]
189#[derive(Eq, Hash, EqIgnoreSpan)]
190pub struct UniversalSelector {
191    pub span: Span,
192    #[cfg_attr(
193        feature = "encoding-impl",
194        encoding(with = "cbor4ii::core::types::Maybe")
195    )]
196    pub prefix: Option<NamespacePrefix>,
197}
198
199#[ast_node("NamespacePrefix")]
200#[derive(Eq, Hash, EqIgnoreSpan)]
201pub struct NamespacePrefix {
202    pub span: Span,
203    #[cfg_attr(
204        feature = "encoding-impl",
205        encoding(with = "cbor4ii::core::types::Maybe")
206    )]
207    pub namespace: Option<Namespace>,
208}
209
210#[ast_node(no_unknown)]
211#[derive(Eq, Hash, Is, EqIgnoreSpan)]
212pub enum Namespace {
213    #[tag("NamedNamespace")]
214    Named(NamedNamespace),
215    #[tag("AnyNamespace")]
216    Any(AnyNamespace),
217}
218
219#[ast_node("NamedNamespace")]
220#[derive(Eq, Hash, EqIgnoreSpan)]
221pub struct NamedNamespace {
222    pub span: Span,
223    pub name: Ident,
224}
225
226#[ast_node("AnyNamespace")]
227#[derive(Eq, Hash, EqIgnoreSpan)]
228pub struct AnyNamespace {
229    pub span: Span,
230}
231
232#[ast_node("WqName")]
233#[derive(Eq, Hash, EqIgnoreSpan)]
234pub struct WqName {
235    pub span: Span,
236    #[cfg_attr(
237        feature = "encoding-impl",
238        encoding(with = "cbor4ii::core::types::Maybe")
239    )]
240    pub prefix: Option<NamespacePrefix>,
241    pub value: Ident,
242}
243
244#[ast_node(no_unknown)]
245#[derive(Eq, Hash, Is, EqIgnoreSpan)]
246pub enum SubclassSelector {
247    #[tag("IdSelector")]
248    Id(IdSelector),
249
250    #[tag("ClassSelector")]
251    Class(ClassSelector),
252
253    #[tag("AttributeSelector")]
254    Attribute(Box<AttributeSelector>),
255
256    #[tag("PseudoClassSelector")]
257    PseudoClass(PseudoClassSelector),
258
259    #[tag("PseudoElementSelector")]
260    PseudoElement(PseudoElementSelector),
261}
262
263#[ast_node("IdSelector")]
264#[derive(Eq, Hash, EqIgnoreSpan)]
265pub struct IdSelector {
266    pub span: Span,
267    /// Does not include `#`
268    pub text: Ident,
269}
270
271#[ast_node("ClassSelector")]
272#[derive(Eq, Hash, EqIgnoreSpan)]
273pub struct ClassSelector {
274    pub span: Span,
275    /// Does not include `.`
276    pub text: Ident,
277}
278
279#[ast_node("AttributeSelector")]
280#[derive(Eq, Hash, EqIgnoreSpan)]
281pub struct AttributeSelector {
282    pub span: Span,
283    pub name: WqName,
284    #[cfg_attr(
285        feature = "encoding-impl",
286        encoding(with = "cbor4ii::core::types::Maybe")
287    )]
288    pub matcher: Option<AttributeSelectorMatcher>,
289    #[cfg_attr(
290        feature = "encoding-impl",
291        encoding(with = "cbor4ii::core::types::Maybe")
292    )]
293    pub value: Option<AttributeSelectorValue>,
294    #[cfg_attr(
295        feature = "encoding-impl",
296        encoding(with = "cbor4ii::core::types::Maybe")
297    )]
298    pub modifier: Option<AttributeSelectorModifier>,
299}
300
301#[derive(StringEnum, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Hash, Is, EqIgnoreSpan)]
302#[cfg_attr(
303    feature = "rkyv",
304    derive(rkyv::Archive, rkyv::Serialize, rkyv::Deserialize)
305)]
306#[cfg_attr(feature = "rkyv", derive(bytecheck::CheckBytes))]
307#[cfg_attr(feature = "rkyv", repr(u32))]
308//#[cfg_attr(
309//    feature = "rkyv",
310//    archive(bound(serialize = "__S: rkyv::ser::ScratchSpace +
311// rkyv::ser::Serializer"))
312//)]
313#[cfg_attr(
314    feature = "encoding-impl",
315    derive(::swc_common::Encode, ::swc_common::Decode)
316)]
317pub enum AttributeSelectorMatcherValue {
318    /// `=`
319    Equals,
320
321    /// `~=`
322    Tilde,
323
324    /// `|=`
325    Bar,
326
327    /// `^=`
328    Caret,
329
330    /// `$=`
331    Dollar,
332
333    /// `*=`
334    Asterisk,
335}
336
337#[ast_node("AttributeSelectorMatcher")]
338#[derive(Eq, Hash, EqIgnoreSpan)]
339pub struct AttributeSelectorMatcher {
340    pub span: Span,
341    pub value: AttributeSelectorMatcherValue,
342}
343
344#[ast_node(no_unknown)]
345#[derive(Eq, Hash, Is, EqIgnoreSpan)]
346pub enum AttributeSelectorValue {
347    #[tag("String")]
348    Str(Str),
349
350    #[tag("Ident")]
351    Ident(Ident),
352}
353
354#[ast_node("AttributeSelectorModifier")]
355#[derive(Eq, Hash, EqIgnoreSpan)]
356pub struct AttributeSelectorModifier {
357    pub span: Span,
358    pub value: Ident,
359}
360
361#[ast_node("PseudoClassSelector")]
362#[derive(Eq, Hash, EqIgnoreSpan)]
363pub struct PseudoClassSelector {
364    pub span: Span,
365    pub name: Ident,
366    #[cfg_attr(
367        feature = "encoding-impl",
368        encoding(with = "cbor4ii::core::types::Maybe")
369    )]
370    pub children: Option<Vec<PseudoClassSelectorChildren>>,
371}
372
373#[ast_node(no_unknown)]
374#[derive(Eq, Hash, Is, EqIgnoreSpan)]
375pub enum PseudoClassSelectorChildren {
376    #[tag("TokenAndSpan")]
377    PreservedToken(TokenAndSpan),
378
379    #[tag("AnPlusB")]
380    AnPlusB(AnPlusB),
381
382    #[tag("Ident")]
383    Ident(Ident),
384
385    #[tag("Str")]
386    Str(Str),
387
388    #[tag("Delimiter")]
389    Delimiter(Delimiter),
390
391    #[tag("ComplexSelector")]
392    ComplexSelector(ComplexSelector),
393
394    #[tag("SelectorList")]
395    SelectorList(SelectorList),
396
397    #[tag("ForgivingSelectorList")]
398    ForgivingSelectorList(ForgivingSelectorList),
399
400    #[tag("CompoundSelectorList")]
401    CompoundSelectorList(CompoundSelectorList),
402
403    #[tag("RelativeSelectorList")]
404    RelativeSelectorList(RelativeSelectorList),
405
406    #[tag("ForgivingRelativeSelectorList")]
407    ForgivingRelativeSelectorList(ForgivingRelativeSelectorList),
408
409    #[tag("CompoundSelector")]
410    CompoundSelector(CompoundSelector),
411}
412
413#[ast_node(no_unknown)]
414#[derive(Eq, Hash, Is, EqIgnoreSpan)]
415pub enum AnPlusB {
416    #[tag("Ident")]
417    Ident(Ident),
418    #[tag("AnPlusBNotation")]
419    AnPlusBNotation(AnPlusBNotation),
420}
421
422#[ast_node("AnPlusBNotation")]
423#[derive(Eq, Hash, EqIgnoreSpan)]
424pub struct AnPlusBNotation {
425    pub span: Span,
426    #[cfg_attr(
427        feature = "encoding-impl",
428        encoding(with = "cbor4ii::core::types::Maybe")
429    )]
430    pub a: Option<i32>,
431    #[cfg_attr(
432        feature = "encoding-impl",
433        encoding(with = "cbor4ii::core::types::Maybe")
434    )]
435    pub a_raw: Option<Atom>,
436    #[cfg_attr(
437        feature = "encoding-impl",
438        encoding(with = "cbor4ii::core::types::Maybe")
439    )]
440    pub b: Option<i32>,
441    #[cfg_attr(
442        feature = "encoding-impl",
443        encoding(with = "cbor4ii::core::types::Maybe")
444    )]
445    pub b_raw: Option<Atom>,
446}
447
448#[ast_node("PseudoElementSelector")]
449#[derive(Eq, Hash, EqIgnoreSpan)]
450pub struct PseudoElementSelector {
451    pub span: Span,
452    pub name: Ident,
453    #[cfg_attr(
454        feature = "encoding-impl",
455        encoding(with = "cbor4ii::core::types::Maybe")
456    )]
457    pub children: Option<Vec<PseudoElementSelectorChildren>>,
458}
459
460#[ast_node(no_unknown)]
461#[derive(Eq, Hash, Is, EqIgnoreSpan)]
462pub enum PseudoElementSelectorChildren {
463    #[tag("TokenAndSpan")]
464    PreservedToken(TokenAndSpan),
465    #[tag("Ident")]
466    Ident(Ident),
467    #[tag("CompoundSelector")]
468    CompoundSelector(CompoundSelector),
469    #[tag("CustomHighlightName")]
470    CustomHighlightName(CustomHighlightName),
471}
472
473#[ast_node("CustomHighlightName")]
474#[derive(Eq, Hash)]
475pub struct CustomHighlightName {
476    pub span: Span,
477
478    pub value: Atom,
479    #[cfg_attr(
480        feature = "encoding-impl",
481        encoding(with = "cbor4ii::core::types::Maybe")
482    )]
483    pub raw: Option<Atom>,
484}
485
486impl EqIgnoreSpan for CustomHighlightName {
487    fn eq_ignore_span(&self, other: &Self) -> bool {
488        self.value == other.value
489    }
490}