11use crate :: compat:: Feature ;
22use crate :: error:: { ParserError , PrinterError } ;
33use crate :: printer:: Printer ;
4+ use crate :: properties:: custom:: TokenList ;
45use crate :: rules:: { StyleContext , ToCssWithContext } ;
5- use crate :: stylesheet:: PrinterOptions ;
6+ use crate :: stylesheet:: { ParserOptions , PrinterOptions } ;
67use crate :: targets:: Browsers ;
78use crate :: traits:: { Parse , ToCss } ;
89use crate :: vendor_prefix:: VendorPrefix ;
@@ -89,20 +90,20 @@ impl<'i> SelectorImpl<'i> for Selectors {
8990 }
9091}
9192
92- pub struct SelectorParser < ' a , ' i > {
93+ pub struct SelectorParser < ' a , ' o , ' i > {
9394 pub default_namespace : & ' a Option < CowArcStr < ' i > > ,
9495 pub namespace_prefixes : & ' a HashMap < CowArcStr < ' i > , CowArcStr < ' i > > ,
9596 pub is_nesting_allowed : bool ,
96- pub css_modules : bool ,
97+ pub options : & ' a ParserOptions < ' o , ' i > ,
9798}
9899
99- impl < ' a , ' i > parcel_selectors:: parser:: Parser < ' i > for SelectorParser < ' a , ' i > {
100+ impl < ' a , ' o , ' i > parcel_selectors:: parser:: Parser < ' i > for SelectorParser < ' a , ' o , ' i > {
100101 type Impl = Selectors ;
101102 type Error = ParserError < ' i > ;
102103
103104 fn parse_non_ts_pseudo_class (
104105 & self ,
105- _ : SourceLocation ,
106+ loc : SourceLocation ,
106107 name : CowRcStr < ' i > ,
107108 ) -> Result < PseudoClass < ' i > , ParseError < ' i , Self :: Error > > {
108109 use PseudoClass :: * ;
@@ -188,7 +189,10 @@ impl<'a, 'i> parcel_selectors::parser::Parser<'i> for SelectorParser<'a, 'i> {
188189 "corner-present" => WebKitScrollbar ( WebKitScrollbarPseudoClass :: CornerPresent ) ,
189190 "window-inactive" => WebKitScrollbar ( WebKitScrollbarPseudoClass :: WindowInactive ) ,
190191
191- _ => Custom ( name. into( ) )
192+ _ => {
193+ self . options. warn( loc. new_custom_error( SelectorParseErrorKind :: UnsupportedPseudoClassOrElement ( name. clone( ) ) ) ) ;
194+ Custom ( name. into( ) )
195+ }
192196 } ;
193197
194198 Ok ( pseudo_class)
@@ -210,9 +214,12 @@ impl<'a, 'i> parcel_selectors::parser::Parser<'i> for SelectorParser<'a, 'i> {
210214 Lang ( langs)
211215 } ,
212216 "dir" => Dir ( Direction :: parse( parser) ?) ,
213- "local" if self . css_modules => Local ( Box :: new( parcel_selectors:: parser:: Selector :: parse( self , parser) ?) ) ,
214- "global" if self . css_modules => Global ( Box :: new( parcel_selectors:: parser:: Selector :: parse( self , parser) ?) ) ,
215- _ => return Err ( parser. new_custom_error( parcel_selectors:: parser:: SelectorParseErrorKind :: UnexpectedIdent ( name. clone( ) ) ) ) ,
217+ "local" if self . options. css_modules. is_some( ) => Local ( Box :: new( parcel_selectors:: parser:: Selector :: parse( self , parser) ?) ) ,
218+ "global" if self . options. css_modules. is_some( ) => Global ( Box :: new( parcel_selectors:: parser:: Selector :: parse( self , parser) ?) ) ,
219+ _ => {
220+ self . options. warn( parser. new_custom_error( SelectorParseErrorKind :: UnsupportedPseudoClassOrElement ( name. clone( ) ) ) ) ;
221+ CustomFunction ( name. into( ) , TokenList :: parse( parser, & self . options, 0 ) ?)
222+ } ,
216223 } ;
217224
218225 Ok ( pseudo_class)
@@ -228,7 +235,7 @@ impl<'a, 'i> parcel_selectors::parser::Parser<'i> for SelectorParser<'a, 'i> {
228235
229236 fn parse_pseudo_element (
230237 & self ,
231- _ : SourceLocation ,
238+ loc : SourceLocation ,
232239 name : CowRcStr < ' i > ,
233240 ) -> Result < PseudoElement < ' i > , ParseError < ' i , Self :: Error > > {
234241 use PseudoElement :: * ;
@@ -260,7 +267,10 @@ impl<'a, 'i> parcel_selectors::parser::Parser<'i> for SelectorParser<'a, 'i> {
260267 "-webkit-scrollbar-corner" => WebKitScrollbar ( WebKitScrollbarPseudoElement :: Corner ) ,
261268 "-webkit-resizer" => WebKitScrollbar ( WebKitScrollbarPseudoElement :: Resizer ) ,
262269
263- _ => Custom ( name. into( ) )
270+ _ => {
271+ self . options. warn( loc. new_custom_error( SelectorParseErrorKind :: UnsupportedPseudoClassOrElement ( name. clone( ) ) ) ) ;
272+ Custom ( name. into( ) )
273+ }
264274 } ;
265275
266276 Ok ( pseudo_element)
@@ -275,7 +285,10 @@ impl<'a, 'i> parcel_selectors::parser::Parser<'i> for SelectorParser<'a, 'i> {
275285 let pseudo_element = match_ignore_ascii_case ! { & name,
276286 "cue" => CueFunction ( Box :: new( Selector :: parse( self , arguments) ?) ) ,
277287 "cue-region" => CueRegionFunction ( Box :: new( Selector :: parse( self , arguments) ?) ) ,
278- _ => return Err ( arguments. new_custom_error( SelectorParseErrorKind :: UnsupportedPseudoClassOrElement ( name) ) )
288+ _ => {
289+ self . options. warn( arguments. new_custom_error( SelectorParseErrorKind :: UnsupportedPseudoClassOrElement ( name. clone( ) ) ) ) ;
290+ CustomFunction ( name. into( ) , TokenList :: parse( arguments, & self . options, 0 ) ?)
291+ }
279292 } ;
280293
281294 Ok ( pseudo_element)
@@ -324,7 +337,7 @@ enum_property! {
324337}
325338
326339/// https://drafts.csswg.org/selectors-4/#structural-pseudos
327- #[ derive( Clone , Eq , PartialEq ) ]
340+ #[ derive( Clone , PartialEq ) ]
328341pub enum PseudoClass < ' i > {
329342 // https://drafts.csswg.org/selectors-4/#linguistic-pseudos
330343 Lang ( Vec < CowArcStr < ' i > > ) ,
@@ -395,6 +408,7 @@ pub enum PseudoClass<'i> {
395408 WebKitScrollbar ( WebKitScrollbarPseudoClass ) ,
396409
397410 Custom ( CowArcStr < ' i > ) ,
411+ CustomFunction ( CowArcStr < ' i > , TokenList < ' i > ) ,
398412}
399413
400414/// https://webkit.org/blog/363/styling-scrollbars/
@@ -622,6 +636,13 @@ impl<'a, 'i> ToCssWithContext<'a, 'i> for PseudoClass<'i> {
622636 dest. write_char ( ':' ) ?;
623637 return dest. write_str ( & val) ;
624638 }
639+ CustomFunction ( name, args) => {
640+ dest. write_char ( ':' ) ?;
641+ dest. write_str ( name) ?;
642+ dest. write_char ( '(' ) ?;
643+ args. to_css ( dest, false ) ?;
644+ dest. write_char ( ')' )
645+ }
625646 }
626647 }
627648}
@@ -665,7 +686,7 @@ impl<'i> PseudoClass<'i> {
665686 }
666687}
667688
668- #[ derive( PartialEq , Eq , Clone , Debug ) ]
689+ #[ derive( PartialEq , Clone , Debug ) ]
669690pub enum PseudoElement < ' i > {
670691 After ,
671692 Before ,
@@ -682,6 +703,7 @@ pub enum PseudoElement<'i> {
682703 CueFunction ( Box < Selector < ' i , Selectors > > ) ,
683704 CueRegionFunction ( Box < Selector < ' i , Selectors > > ) ,
684705 Custom ( CowArcStr < ' i > ) ,
706+ CustomFunction ( CowArcStr < ' i > , TokenList < ' i > ) ,
685707}
686708
687709#[ derive( PartialEq , Eq , Clone , Debug , Hash ) ]
@@ -796,6 +818,13 @@ impl<'i> ToCss for PseudoElement<'i> {
796818 dest. write_str ( "::" ) ?;
797819 return dest. write_str ( val) ;
798820 }
821+ CustomFunction ( name, args) => {
822+ dest. write_str ( "::" ) ?;
823+ dest. write_str ( name) ?;
824+ dest. write_char ( '(' ) ?;
825+ args. to_css ( dest, false ) ?;
826+ dest. write_char ( ')' )
827+ }
799828 }
800829 }
801830}
0 commit comments