@@ -85,17 +85,103 @@ impl<L: LengthNum> MediaQueryStatus<L> {
8585 }
8686}
8787
88+ pub trait StyleNodeClass {
89+ fn name ( & self ) -> & str ;
90+ fn scope ( & self ) -> Option < NonZeroUsize > ;
91+ }
92+
93+ impl StyleNodeClass for ( String , Option < NonZeroUsize > ) {
94+ fn name ( & self ) -> & str {
95+ & self . 0
96+ }
97+
98+ fn scope ( & self ) -> Option < NonZeroUsize > {
99+ self . 1
100+ }
101+ }
102+
103+ pub enum StyleNodeAttributeCaseSensitivity {
104+ CaseSensitive ,
105+ CaseInsensitive ,
106+ }
107+
108+ impl StyleNodeAttributeCaseSensitivity {
109+ pub fn eq ( & self , a : & str , b : & str ) -> bool {
110+ match self {
111+ Self :: CaseSensitive => a == b,
112+ Self :: CaseInsensitive => a. eq_ignore_ascii_case ( b) ,
113+ }
114+ }
115+
116+ pub fn starts_with ( & self , a : & str , b : & str ) -> bool {
117+ // FIXME: reduce memory allocation
118+ match self {
119+ Self :: CaseSensitive => a. starts_with ( b) ,
120+ Self :: CaseInsensitive => a. to_ascii_lowercase ( ) . starts_with ( & b. to_ascii_lowercase ( ) ) ,
121+ }
122+ }
123+
124+ pub fn ends_with ( & self , a : & str , b : & str ) -> bool {
125+ // FIXME: reduce memory allocation
126+ match self {
127+ Self :: CaseSensitive => a. ends_with ( b) ,
128+ Self :: CaseInsensitive => a. to_ascii_lowercase ( ) . ends_with ( & b. to_ascii_lowercase ( ) ) ,
129+ }
130+ }
131+
132+ pub fn contains ( & self , a : & str , b : & str ) -> bool {
133+ // FIXME: reduce memory allocation
134+ match self {
135+ Self :: CaseSensitive => a. contains ( b) ,
136+ Self :: CaseInsensitive => a. to_ascii_lowercase ( ) . contains ( & b. to_ascii_lowercase ( ) ) ,
137+ }
138+ }
139+ }
140+
141+ pub trait StyleNode {
142+ type Class : StyleNodeClass ;
143+ type ClassIter < ' a > : Iterator < Item = & ' a Self :: Class >
144+ where
145+ Self : ' a ;
146+
147+ fn style_scope ( & self ) -> Option < NonZeroUsize > ;
148+ fn extra_style_scope ( & self ) -> Option < NonZeroUsize > ;
149+ fn host_style_scope ( & self ) -> Option < NonZeroUsize > ;
150+ fn tag_name ( & self ) -> & str ;
151+ fn id ( & self ) -> Option < & str > ;
152+ fn classes ( & self ) -> Self :: ClassIter < ' _ > ;
153+ fn attribute ( & self , name : & str ) -> Option < ( & str , StyleNodeAttributeCaseSensitivity ) > ;
154+
155+ fn contain_scope ( & self , scope : Option < NonZeroUsize > ) -> bool {
156+ scope. is_none ( )
157+ || self . style_scope ( ) == scope
158+ || self . extra_style_scope ( ) == scope
159+ || self . host_style_scope ( ) == scope
160+ }
161+ }
162+
88163/// Represents node information, used for matching rules.
89- #[ derive( Clone , Debug ) ]
164+ #[ derive( Debug ) ]
90165pub struct StyleQuery < ' a > {
91166 pub ( super ) style_scope : Option < NonZeroUsize > ,
92167 pub ( super ) extra_style_scope : Option < NonZeroUsize > ,
93168 pub ( super ) host_style_scope : Option < NonZeroUsize > ,
94169 pub ( super ) tag_name : & ' a str ,
95170 pub ( super ) id : & ' a str ,
96171 pub ( super ) classes : & ' a [ ( String , Option < NonZeroUsize > ) ] ,
97- #[ allow( unused) ]
98- pub ( super ) attributes : & ' a [ String ] , // TODO support attributes
172+ }
173+
174+ impl Clone for StyleQuery < ' _ > {
175+ fn clone ( & self ) -> Self {
176+ Self {
177+ style_scope : self . style_scope ,
178+ extra_style_scope : self . extra_style_scope ,
179+ host_style_scope : self . host_style_scope ,
180+ tag_name : self . tag_name ,
181+ id : self . id ,
182+ classes : self . classes ,
183+ }
184+ }
99185}
100186
101187impl < ' a > StyleQuery < ' a > {
@@ -107,7 +193,6 @@ impl<'a> StyleQuery<'a> {
107193 tag_name : & ' a str ,
108194 id : & ' a str ,
109195 classes : & ' a [ ( String , Option < NonZeroUsize > ) ] ,
110- attributes : & ' a [ String ] ,
111196 ) -> Self {
112197 Self {
113198 style_scope,
@@ -116,15 +201,79 @@ impl<'a> StyleQuery<'a> {
116201 tag_name,
117202 id,
118203 classes,
119- attributes,
120204 }
121205 }
206+ }
122207
123- pub ( crate ) fn contain_scope ( & self , scope : Option < NonZeroUsize > ) -> bool {
124- scope. is_none ( )
125- || self . style_scope == scope
126- || self . extra_style_scope == scope
127- || self . host_style_scope == scope
208+ impl < ' a > StyleNode for StyleQuery < ' a > {
209+ type Class = ( String , Option < NonZeroUsize > ) ;
210+ type ClassIter < ' c >
211+ = core:: slice:: Iter < ' c , Self :: Class >
212+ where
213+ ' a : ' c ;
214+
215+ fn style_scope ( & self ) -> Option < NonZeroUsize > {
216+ self . style_scope
217+ }
218+
219+ fn extra_style_scope ( & self ) -> Option < NonZeroUsize > {
220+ self . extra_style_scope
221+ }
222+
223+ fn host_style_scope ( & self ) -> Option < NonZeroUsize > {
224+ self . host_style_scope
225+ }
226+
227+ fn tag_name ( & self ) -> & str {
228+ self . tag_name
229+ }
230+
231+ fn id ( & self ) -> Option < & str > {
232+ Some ( self . id )
233+ }
234+
235+ fn classes ( & self ) -> Self :: ClassIter < ' _ > {
236+ self . classes . iter ( )
237+ }
238+
239+ fn attribute ( & self , name : & str ) -> Option < ( & str , StyleNodeAttributeCaseSensitivity ) > {
240+ None
241+ }
242+ }
243+
244+ impl < ' b , ' a : ' b > StyleNode for & ' b StyleQuery < ' a > {
245+ type Class = ( String , Option < NonZeroUsize > ) ;
246+ type ClassIter < ' c >
247+ = core:: slice:: Iter < ' c , Self :: Class >
248+ where
249+ ' b : ' c ;
250+
251+ fn style_scope ( & self ) -> Option < NonZeroUsize > {
252+ self . style_scope
253+ }
254+
255+ fn extra_style_scope ( & self ) -> Option < NonZeroUsize > {
256+ self . extra_style_scope
257+ }
258+
259+ fn host_style_scope ( & self ) -> Option < NonZeroUsize > {
260+ self . host_style_scope
261+ }
262+
263+ fn tag_name ( & self ) -> & str {
264+ self . tag_name
265+ }
266+
267+ fn id ( & self ) -> Option < & str > {
268+ Some ( self . id )
269+ }
270+
271+ fn classes ( & self ) -> Self :: ClassIter < ' _ > {
272+ self . classes . iter ( )
273+ }
274+
275+ fn attribute ( & self , name : & str ) -> Option < ( & str , StyleNodeAttributeCaseSensitivity ) > {
276+ None
128277 }
129278}
130279
0 commit comments