hpx_browser/css_selectors/
ast.rs1pub type SelectorList = Vec<Selector>;
3
4#[derive(Debug, Clone, PartialEq)]
6pub struct Selector {
7 pub(crate) components: Vec<Component>,
8 pub(crate) specificity: Specificity,
9}
10
11impl Selector {
12 pub fn new(components: Vec<Component>, specificity: Specificity) -> Self {
13 Self {
14 components,
15 specificity,
16 }
17 }
18
19 pub fn components(&self) -> &[Component] {
20 &self.components
21 }
22
23 pub fn specificity(&self) -> Specificity {
24 self.specificity
25 }
26}
27
28#[derive(Debug, Clone, PartialEq)]
30pub enum Component {
31 Combinator(Combinator),
32 Simple(SimpleSelector),
33}
34
35#[derive(Debug, Clone, Copy, PartialEq, Eq)]
36pub enum Combinator {
37 Descendant,
38 Child,
39 NextSibling,
40 SubsequentSibling,
41}
42
43#[derive(Debug, Clone, PartialEq)]
44pub enum SimpleSelector {
45 Type(String),
46 Universal,
47 Id(String),
48 Class(String),
49 Attribute {
50 name: String,
51 operator: Option<AttributeOperator>,
52 value: Option<String>,
53 case_sensitivity: CaseSensitivity,
54 },
55 PseudoClass(PseudoClass),
56 PseudoElement(PseudoElement),
57 Nesting,
58}
59
60#[derive(Debug, Clone, Copy, PartialEq, Eq)]
61pub enum AttributeOperator {
62 Exact,
63 Includes,
64 DashMatch,
65 Prefix,
66 Suffix,
67 Substring,
68}
69
70#[derive(Debug, Clone, Copy, PartialEq, Eq)]
71pub enum CaseSensitivity {
72 Default,
73 CaseInsensitive,
74 CaseSensitive,
75}
76
77#[derive(Debug, Clone, PartialEq)]
78pub enum PseudoClass {
79 AnyLink,
80 Link,
81 Visited,
82 Target,
83 Hover,
84 Active,
85 Focus,
86 FocusWithin,
87 FocusVisible,
88 Enabled,
89 Disabled,
90 ReadWrite,
91 ReadOnly,
92 Checked,
93 Default,
94 Indeterminate,
95 Required,
96 Optional,
97 Valid,
98 Invalid,
99 InRange,
100 OutOfRange,
101 PlaceholderShown,
102 Root,
103 Empty,
104 FirstChild,
105 LastChild,
106 OnlyChild,
107 FirstOfType,
108 LastOfType,
109 OnlyOfType,
110 NthChild(NthExpr, Option<SelectorList>),
111 NthLastChild(NthExpr, Option<SelectorList>),
112 NthOfType(NthExpr),
113 NthLastOfType(NthExpr),
114 Lang(Vec<String>),
115 Is(SelectorList),
116 Not(SelectorList),
117 Where(SelectorList),
118 Has(Vec<RelativeSelector>),
119}
120
121#[derive(Debug, Clone, Copy, PartialEq, Eq)]
123pub struct NthExpr {
124 pub a: i32,
125 pub b: i32,
126}
127
128impl NthExpr {
129 pub fn matches(&self, index: i32) -> bool {
130 if self.a == 0 {
131 return index == self.b;
132 }
133 let diff = index - self.b;
134 if self.a > 0 {
135 diff >= 0 && diff % self.a == 0
136 } else {
137 diff <= 0 && diff % self.a == 0
138 }
139 }
140}
141
142#[derive(Debug, Clone, PartialEq)]
143pub struct RelativeSelector {
144 pub combinator: Option<Combinator>,
145 pub selector: Selector,
146}
147
148#[derive(Debug, Clone, PartialEq)]
149pub enum PseudoElement {
150 Before,
151 After,
152 FirstLine,
153 FirstLetter,
154 Placeholder,
155 Selection,
156 Part(Vec<String>),
157 Slotted(Box<Selector>),
158 Custom(String),
159}
160
161#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Default)]
163pub struct Specificity {
164 pub a: u32,
165 pub b: u32,
166 pub c: u32,
167}
168
169impl Specificity {
170 pub fn new(a: u32, b: u32, c: u32) -> Self {
171 Self { a, b, c }
172 }
173
174 pub fn max(self, other: Self) -> Self {
175 if self >= other { self } else { other }
176 }
177}
178
179impl std::ops::Add for Specificity {
180 type Output = Self;
181 fn add(self, rhs: Self) -> Self {
182 Self {
183 a: self.a + rhs.a,
184 b: self.b + rhs.b,
185 c: self.c + rhs.c,
186 }
187 }
188}
189
190impl std::ops::AddAssign for Specificity {
191 fn add_assign(&mut self, rhs: Self) {
192 self.a += rhs.a;
193 self.b += rhs.b;
194 self.c += rhs.c;
195 }
196}