@@ -37,11 +37,8 @@ use stylist::SelectorMap;
37
37
/// unnecessary.
38
38
#[ derive( Debug , Clone , PartialEq ) ]
39
39
pub struct RestyleHint {
40
- /// Rerun selector matching on the element.
41
- match_self : bool ,
42
-
43
- /// Rerun selector matching on all of the element's descendants.
44
- match_descendants : bool ,
40
+ /// Depths at which selector matching must be re-run.
41
+ match_under_self : RestyleDepths ,
45
42
46
43
/// Rerun selector matching on all later siblings of the element and all
47
44
/// of their descendants.
@@ -82,6 +79,75 @@ bitflags! {
82
79
}
83
80
}
84
81
82
+ /// Eight bit wide bitfield representing depths of a DOM subtree's descendants,
83
+ /// used to represent which elements must have selector matching re-run on them.
84
+ ///
85
+ /// The least significant bit indicates that selector matching must be re-run
86
+ /// for the element itself, the second least significant bit for the element's
87
+ /// children, the third its grandchildren, and so on. If the most significant
88
+ /// bit it set, it indicates that that selector matching must be re-run for
89
+ /// elements at that depth and all of their descendants.
90
+ #[ derive( Debug , Clone , Copy , PartialEq ) ]
91
+ struct RestyleDepths ( u8 ) ;
92
+
93
+ impl RestyleDepths {
94
+ /// Returns a `RestyleDepths` representing no element depths.
95
+ fn empty ( ) -> Self {
96
+ RestyleDepths ( 0 )
97
+ }
98
+
99
+ /// Returns a `RestyleDepths` representing the current element depth.
100
+ fn for_self ( ) -> Self {
101
+ RestyleDepths ( 0x01 )
102
+ }
103
+
104
+ /// Returns a `RestyleDepths` representing the depths of all descendants of
105
+ /// the current element.
106
+ fn for_descendants ( ) -> Self {
107
+ RestyleDepths ( 0xfe )
108
+ }
109
+
110
+ /// Returns a `RestyleDepths` representing the current element depth and the
111
+ /// depths of all the current element's descendants.
112
+ fn for_self_and_descendants ( ) -> Self {
113
+ RestyleDepths ( 0xff )
114
+ }
115
+
116
+ /// Returns whether this `RestyleDepths` represents the current element
117
+ /// depth and the depths of all the current element's descendants.
118
+ fn is_self_and_descendants ( & self ) -> bool {
119
+ self . 0 == 0xff
120
+ }
121
+
122
+ /// Returns whether this `RestyleDepths` includes any element depth.
123
+ fn is_any ( & self ) -> bool {
124
+ self . 0 != 0
125
+ }
126
+
127
+ /// Returns whether this `RestyleDepths` includes the current element depth.
128
+ fn has_self ( & self ) -> bool {
129
+ ( self . 0 & 0x01 ) != 0
130
+ }
131
+
132
+ /// Returns a new `RestyleDepths` with all depth values represented by this
133
+ /// `RestyleDepths` reduced by one.
134
+ fn propagate ( & self ) -> Self {
135
+ RestyleDepths ( ( self . 0 >> 1 ) | ( self . 0 & 0x80 ) )
136
+ }
137
+
138
+ /// Returns a new `RestyleDepths` that represents the union of the depths
139
+ /// from `self` and `other`.
140
+ fn insert ( & mut self , other : RestyleDepths ) {
141
+ self . 0 |= other. 0 ;
142
+ }
143
+
144
+ /// Returns whether this `RestyleDepths` includes all depths represented
145
+ /// by `other`.
146
+ fn contains ( & self , other : RestyleDepths ) -> bool {
147
+ ( self . 0 & other. 0 ) == other. 0
148
+ }
149
+ }
150
+
85
151
/// Asserts that all RestyleReplacements have a matching nsRestyleHint value.
86
152
#[ cfg( feature = "gecko" ) ]
87
153
#[ inline]
@@ -116,8 +182,7 @@ impl RestyleHint {
116
182
#[ inline]
117
183
pub fn empty ( ) -> Self {
118
184
RestyleHint {
119
- match_self : false ,
120
- match_descendants : false ,
185
+ match_under_self : RestyleDepths :: empty ( ) ,
121
186
match_later_siblings : false ,
122
187
replacements : RestyleReplacements :: empty ( ) ,
123
188
}
@@ -128,8 +193,7 @@ impl RestyleHint {
128
193
#[ inline]
129
194
pub fn for_self ( ) -> Self {
130
195
RestyleHint {
131
- match_self : true ,
132
- match_descendants : false ,
196
+ match_under_self : RestyleDepths :: for_self ( ) ,
133
197
match_later_siblings : false ,
134
198
replacements : RestyleReplacements :: empty ( ) ,
135
199
}
@@ -140,8 +204,7 @@ impl RestyleHint {
140
204
#[ inline]
141
205
pub fn descendants ( ) -> Self {
142
206
RestyleHint {
143
- match_self : false ,
144
- match_descendants : true ,
207
+ match_under_self : RestyleDepths :: for_descendants ( ) ,
145
208
match_later_siblings : false ,
146
209
replacements : RestyleReplacements :: empty ( ) ,
147
210
}
@@ -152,8 +215,7 @@ impl RestyleHint {
152
215
#[ inline]
153
216
pub fn later_siblings ( ) -> Self {
154
217
RestyleHint {
155
- match_self : false ,
156
- match_descendants : false ,
218
+ match_under_self : RestyleDepths :: empty ( ) ,
157
219
match_later_siblings : true ,
158
220
replacements : RestyleReplacements :: empty ( ) ,
159
221
}
@@ -164,8 +226,7 @@ impl RestyleHint {
164
226
#[ inline]
165
227
pub fn subtree ( ) -> Self {
166
228
RestyleHint {
167
- match_self : true ,
168
- match_descendants : true ,
229
+ match_under_self : RestyleDepths :: for_self_and_descendants ( ) ,
169
230
match_later_siblings : false ,
170
231
replacements : RestyleReplacements :: empty ( ) ,
171
232
}
@@ -177,8 +238,7 @@ impl RestyleHint {
177
238
#[ inline]
178
239
pub fn subtree_and_later_siblings ( ) -> Self {
179
240
RestyleHint {
180
- match_self : true ,
181
- match_descendants : true ,
241
+ match_under_self : RestyleDepths :: for_self_and_descendants ( ) ,
182
242
match_later_siblings : true ,
183
243
replacements : RestyleReplacements :: empty ( ) ,
184
244
}
@@ -189,8 +249,7 @@ impl RestyleHint {
189
249
#[ inline]
190
250
pub fn for_replacements ( replacements : RestyleReplacements ) -> Self {
191
251
RestyleHint {
192
- match_self : false ,
193
- match_descendants : false ,
252
+ match_under_self : RestyleDepths :: empty ( ) ,
194
253
match_later_siblings : false ,
195
254
replacements : replacements,
196
255
}
@@ -206,14 +265,16 @@ impl RestyleHint {
206
265
/// restyle work, and thus any `insert()` calls will have no effect.
207
266
#[ inline]
208
267
pub fn is_maximum ( & self ) -> bool {
209
- self . match_self && self . match_descendants && self . match_later_siblings && self . replacements . is_all ( )
268
+ self . match_under_self . is_self_and_descendants ( ) &&
269
+ self . match_later_siblings &&
270
+ self . replacements . is_all ( )
210
271
}
211
272
212
273
/// Returns whether the hint specifies that some work must be performed on
213
274
/// the current element.
214
275
#[ inline]
215
276
pub fn affects_self ( & self ) -> bool {
216
- self . match_self || !self . replacements . is_empty ( )
277
+ self . match_self ( ) || !self . replacements . is_empty ( )
217
278
}
218
279
219
280
/// Returns whether the hint specifies that later siblings must be restyled.
@@ -233,25 +294,25 @@ impl RestyleHint {
233
294
/// animation cascade level replacement.
234
295
#[ inline]
235
296
pub fn has_non_animation_hint ( & self ) -> bool {
236
- self . match_self || self . match_descendants || self . match_later_siblings ||
297
+ self . match_under_self . is_any ( ) || self . match_later_siblings ||
237
298
self . replacements . contains ( RESTYLE_STYLE_ATTRIBUTE )
238
299
}
239
300
240
301
/// Returns whether the hint specifies that selector matching must be re-run
241
302
/// for the element.
242
303
#[ inline]
243
304
pub fn match_self ( & self ) -> bool {
244
- self . match_self
305
+ self . match_under_self . has_self ( )
245
306
}
246
307
247
308
/// Returns a new `RestyleHint` appropriate for children of the current
248
309
/// element.
249
310
#[ inline]
250
311
pub fn propagate_for_non_animation_restyle ( & self ) -> Self {
251
- if self . match_descendants {
252
- Self :: subtree ( )
253
- } else {
254
- Self :: empty ( )
312
+ RestyleHint {
313
+ match_under_self : self . match_under_self . propagate ( ) ,
314
+ match_later_siblings : false ,
315
+ replacements : RestyleReplacements :: empty ( ) ,
255
316
}
256
317
}
257
318
@@ -271,8 +332,7 @@ impl RestyleHint {
271
332
/// Unions the specified `RestyleHint` into this one.
272
333
#[ inline]
273
334
pub fn insert_from ( & mut self , other : & Self ) {
274
- self . match_self |= other. match_self ;
275
- self . match_descendants |= other. match_descendants ;
335
+ self . match_under_self . insert ( other. match_under_self ) ;
276
336
self . match_later_siblings |= other. match_later_siblings ;
277
337
self . replacements . insert ( other. replacements ) ;
278
338
}
@@ -289,9 +349,8 @@ impl RestyleHint {
289
349
/// work as the specified one.
290
350
#[ inline]
291
351
pub fn contains ( & mut self , other : & Self ) -> bool {
292
- !( other. match_self && !self . match_self ) &&
293
- !( other. match_descendants && !self . match_descendants ) &&
294
- !( other. match_later_siblings && !self . match_later_siblings ) &&
352
+ self . match_under_self . contains ( other. match_under_self ) &&
353
+ ( self . match_later_siblings & other. match_later_siblings ) == other. match_later_siblings &&
295
354
self . replacements . contains ( other. replacements )
296
355
}
297
356
}
@@ -319,9 +378,16 @@ impl From<nsRestyleHint> for RestyleHint {
319
378
use gecko_bindings:: structs:: nsRestyleHint_eRestyle_SomeDescendants as eRestyle_SomeDescendants;
320
379
use gecko_bindings:: structs:: nsRestyleHint_eRestyle_Subtree as eRestyle_Subtree;
321
380
381
+ let mut match_under_self = RestyleDepths :: empty ( ) ;
382
+ if ( raw. 0 & ( eRestyle_Self. 0 | eRestyle_Subtree. 0 ) ) != 0 {
383
+ match_under_self. insert ( RestyleDepths :: for_self ( ) ) ;
384
+ }
385
+ if ( raw. 0 & ( eRestyle_Subtree. 0 | eRestyle_SomeDescendants. 0 ) ) != 0 {
386
+ match_under_self. insert ( RestyleDepths :: for_descendants ( ) ) ;
387
+ }
388
+
322
389
RestyleHint {
323
- match_self : ( raw. 0 & ( eRestyle_Self. 0 | eRestyle_Subtree. 0 ) ) != 0 ,
324
- match_descendants : ( raw. 0 & ( eRestyle_Subtree. 0 | eRestyle_SomeDescendants. 0 ) ) != 0 ,
390
+ match_under_self : match_under_self,
325
391
match_later_siblings : ( raw. 0 & eRestyle_LaterSiblings. 0 ) != 0 ,
326
392
replacements : raw. into ( ) ,
327
393
}
0 commit comments