2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2018 - 2022 ,  Andreas  Kling  < andreas @ ladybird . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2020 - 2021 ,  the  SerenityOS  developers . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 - 2024 ,  Sam  Atkins  < sam @ ladybird . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 ,  Tobias  Christiansen  < tobyase @ serenityos . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2022 ,  MacDue  < macdue @ dueutil . tech > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2024 ,  Shannon  Booth  < shannon @ serenityos . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2024 ,  Tommy  van  der  Vorst  < tommy @ pixelspark . nl > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2024 ,  Matthew  Olsson  < mattco @ serenityos . org > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2024 ,  Glenn  Skrzypczak  < glenn . skrzypczak @ gmail . com > 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSFontFaceRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSImportRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSKeyframeRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSKeyframesRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSLayerBlockRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSLayerStatementRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSMediaRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSNamespaceRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSNestedDeclarations.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSPropertyRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSStyleRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/CSSSupportsRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/Parser/Parser.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/PropertyName.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleValues/IntegerStyleValue.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleValues/NumberStyleValue.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleValues/OpenTypeTaggedStyleValue.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleValues/PercentageStyleValue.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleValues/StringStyleValue.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleValues/StyleValueList.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  Web : : CSS : : Parser  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								GC : : Ptr < CSSRule >  Parser : : convert_to_rule ( Rule  const &  rule ,  Nested  nested )  
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  rule . visit ( 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        [ this ,  nested ] ( AtRule  const &  at_rule )  - >  GC : : Ptr < CSSRule >  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            if  ( has_ignored_vendor_prefix ( at_rule . name ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( at_rule . name . equals_ignoring_ascii_case ( " font-face " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  convert_to_font_face_rule ( at_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( at_rule . name . equals_ignoring_ascii_case ( " import " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  convert_to_import_rule ( at_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( at_rule . name . equals_ignoring_ascii_case ( " keyframes " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  convert_to_keyframes_rule ( at_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( at_rule . name . equals_ignoring_ascii_case ( " layer " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  convert_to_layer_rule ( at_rule ,  nested ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( at_rule . name . equals_ignoring_ascii_case ( " media " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  convert_to_media_rule ( at_rule ,  nested ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( at_rule . name . equals_ignoring_ascii_case ( " namespace " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  convert_to_namespace_rule ( at_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( at_rule . name . equals_ignoring_ascii_case ( " supports " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  convert_to_supports_rule ( at_rule ,  nested ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( at_rule . name . equals_ignoring_ascii_case ( " property " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  convert_to_property_rule ( at_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // FIXME: More at rules!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Unrecognized CSS at-rule: @{} " ,  at_rule . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } , 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        [ this ,  nested ] ( QualifiedRule  const &  qualified_rule )  - >  GC : : Ptr < CSSRule >  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								            return  convert_to_style_rule ( qualified_rule ,  nested ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								GC : : Ptr < CSSStyleRule >  Parser : : convert_to_style_rule ( QualifiedRule  const &  qualified_rule ,  Nested  nested )  
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TokenStream  prelude_stream  {  qualified_rule . prelude  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  maybe_selectors  =  parse_a_selector_list ( prelude_stream , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        nested  = =  Nested : : Yes  ?  SelectorType : : Relative  :  SelectorType : : Standalone ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( maybe_selectors . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( maybe_selectors . error ( )  = =  ParseError : : SyntaxError )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: style rule selectors invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  constexpr  ( CSS_PARSER_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                prelude_stream . dump_all_tokens ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( maybe_selectors . value ( ) . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: empty selector; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SelectorList  selectors  =  maybe_selectors . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-08 17:50:38 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( nested  = =  Nested : : Yes ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        selectors  =  adapt_nested_relative_selector_list ( selectors ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto *  declaration  =  convert_to_style_declaration ( qualified_rule . declarations ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: style rule declaration invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-12-26 14:32:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    GC : : RootVector < CSSRule * >  child_rules  {  m_context . realm ( ) . heap ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  child  :  qualified_rule . child_rules )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        child . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( Rule  const &  rule )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // "In addition to nested style rules, this specification allows nested group rules inside of style rules:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // any at-rule whose body contains style rules can be nested inside of a style rule as well."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                // https://drafts.csswg.org/css-nesting-1/#nested-group-rules
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( auto  converted_rule  =  convert_to_rule ( rule ,  Nested : : Yes ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( is < CSSGroupingRule > ( * converted_rule ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        child_rules . append ( converted_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: nested {} is not allowed inside style rule; discarding. " ,  converted_rule - > class_name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( Vector < Declaration >  const &  declarations )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto *  declaration  =  convert_to_style_declaration ( declarations ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: nested declarations invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                child_rules . append ( CSSNestedDeclarations : : create ( m_context . realm ( ) ,  * declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  nested_rules  =  CSSRuleList : : create ( m_context . realm ( ) ,  move ( child_rules ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  CSSStyleRule : : create ( m_context . realm ( ) ,  move ( selectors ) ,  * declaration ,  * nested_rules ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								GC : : Ptr < CSSImportRule >  Parser : : convert_to_import_rule ( AtRule  const &  rule )  
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://drafts.csswg.org/css-cascade-5/#at-import
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // @import [ <url> | <string> ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //         [ layer | layer(<layer-name>) ]?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //         <import-conditions> ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // <import-conditions> = [ supports( [ <supports-condition> | <declaration> ] ) ]?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //                      <media-query-list>?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( rule . prelude . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to parse @import rule: Empty prelude. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! rule . child_rules_and_lists_of_declarations . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to parse @import rule: Block is not allowed. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TokenStream  tokens  {  rule . prelude  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < URL : : URL >  url  =  parse_url_function ( tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! url . has_value ( )  & &  tokens . next_token ( ) . is ( Token : : Type : : String ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        url  =  m_context . complete_url ( tokens . consume_a_token ( ) . token ( ) . string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! url . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to parse @import rule: Unable to parse `{}` as URL. " ,  tokens . next_token ( ) . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // TODO: Support layers and import-conditions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  constexpr  ( CSS_PARSER_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln ( " Failed to parse @import rule: Trailing tokens after URL are not yet supported. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tokens . dump_all_tokens ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  CSSImportRule : : create ( url . value ( ) ,  const_cast < DOM : : Document & > ( * m_context . document ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								Optional < FlyString >  Parser : : parse_layer_name ( TokenStream < ComponentValue > &  tokens ,  AllowBlankLayerName  allow_blank_layer_name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://drafts.csswg.org/css-cascade-5/#typedef-layer-name
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // <layer-name> = <ident> [ '.' <ident> ]*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // "The CSS-wide keywords are reserved for future use, and cause the rule to be invalid at parse time if used as an <ident> in the <layer-name>."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  is_valid_layer_name_part  =  [ ] ( auto &  token )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  token . is ( Token : : Type : : Ident )  & &  ! is_css_wide_keyword ( token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! tokens . has_next_token ( )  & &  allow_blank_layer_name  = =  AllowBlankLayerName : : Yes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // No name present, just return a blank one
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  FlyString ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  first_name_token  =  tokens . consume_a_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! is_valid_layer_name_part ( first_name_token ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringBuilder  builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    builder . append ( first_name_token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Repeatedly parse `'.' <ident>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! tokens . next_token ( ) . is_delim ( ' . ' ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tokens . discard_a_token ( ) ;  // '.'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  name_token  =  tokens . consume_a_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! is_valid_layer_name_part ( name_token ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        builder . appendff ( " .{} " ,  name_token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  builder . to_fly_string_without_validation ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								GC : : Ptr < CSSRule >  Parser : : convert_to_layer_rule ( AtRule  const &  rule ,  Nested  nested )  
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://drafts.csswg.org/css-cascade-5/#at-layer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! rule . child_rules_and_lists_of_declarations . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // CSSLayerBlockRule
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // @layer <layer-name>? {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        //   <rule-list>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // First, the name
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        FlyString  layer_name  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  prelude_tokens  =  TokenStream  {  rule . prelude  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  maybe_name  =  parse_layer_name ( prelude_tokens ,  AllowBlankLayerName : : Yes ) ;  maybe_name . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            layer_name  =  maybe_name . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @layer has invalid prelude, (not a valid layer name) prelude = {}; discarding. " ,  rule . prelude ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        prelude_tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( prelude_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @layer has invalid prelude, (tokens after layer name) prelude = {}; discarding. " ,  rule . prelude ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Then the rules
 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-26 14:32:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        GC : : RootVector < CSSRule * >  child_rules  {  m_context . realm ( ) . heap ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-04 17:26:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        for  ( auto  const &  child  :  rule . child_rules_and_lists_of_declarations )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            child . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( Rule  const &  rule )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( auto  child_rule  =  convert_to_rule ( rule ,  nested ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        child_rules . append ( child_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                [ & ] ( Vector < Declaration >  const &  declarations )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto *  declaration  =  convert_to_style_declaration ( declarations ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ! declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: nested declarations invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    child_rules . append ( CSSNestedDeclarations : : create ( m_context . realm ( ) ,  * declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								        auto  rule_list  =  CSSRuleList : : create ( m_context . realm ( ) ,  child_rules ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  CSSLayerBlockRule : : create ( m_context . realm ( ) ,  layer_name ,  rule_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // CSSLayerStatementRule
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // @layer <layer-name>#;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  tokens  =  TokenStream  {  rule . prelude  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < FlyString >  layer_names ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // Comma
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! layer_names . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  comma  =  tokens . consume_a_token ( ) ;  ! comma . is ( Token : : Type : : Comma ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @layer missing separating comma, ({}) prelude = {}; discarding. " ,  comma . to_debug_string ( ) ,  rule . prelude ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  name  =  parse_layer_name ( tokens ,  AllowBlankLayerName : : No ) ;  name . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            layer_names . append ( name . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @layer contains invalid name, prelude = {}; discarding. " ,  rule . prelude ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( layer_names . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @layer statement has no layer names, prelude = {}; discarding. " ,  rule . prelude ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  CSSLayerStatementRule : : create ( m_context . realm ( ) ,  move ( layer_names ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								GC : : Ptr < CSSKeyframesRule >  Parser : : convert_to_keyframes_rule ( AtRule  const &  rule )  
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://drafts.csswg.org/css-animations/#keyframes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // @keyframes = @keyframes <keyframes-name> { <qualified-rule-list> }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // <keyframes-name> = <custom-ident> | <string>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // <keyframe-block> = <keyframe-selector># { <declaration-list> }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // <keyframe-selector> = from | to | <percentage [0,100]>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( rule . prelude . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to parse @keyframes rule: Empty prelude. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // FIXME: Is there some way of detecting if there is a block or not?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  prelude_stream  =  TokenStream  {  rule . prelude  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    prelude_stream . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto &  token  =  prelude_stream . consume_a_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! token . is_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes has invalid prelude, prelude = {}; discarding. " ,  rule . prelude ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  name_token  =  token . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    prelude_stream . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( prelude_stream . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes has invalid prelude, prelude = {}; discarding. " ,  rule . prelude ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( name_token . is ( Token : : Type : : Ident )  & &  ( is_css_wide_keyword ( name_token . ident ( ) )  | |  name_token . ident ( ) . equals_ignoring_ascii_case ( " none " sv ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes rule name is invalid: {}; discarding. " ,  name_token . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! name_token . is ( Token : : Type : : String )  & &  ! name_token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes rule name is invalid: {}; discarding. " ,  name_token . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  name  =  name_token . to_string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-12-26 14:32:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    GC : : RootVector < CSSRule * >  keyframes ( m_context . realm ( ) . heap ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    rule . for_each_as_qualified_rule_list ( [ & ] ( auto &  qualified_rule )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! qualified_rule . child_rules . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes keyframe rule contains at-rules; discarding them. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  selectors  =  Vector < CSS : : Percentage >  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TokenStream  child_tokens  {  qualified_rule . prelude  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        while  ( child_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            child_tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! child_tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  tok  =  child_tokens . consume_a_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! tok . is_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes rule has invalid selector: {}; discarding. " ,  tok . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                child_tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  token  =  tok . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  read_a_selector  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( token . ident ( ) . equals_ignoring_ascii_case ( " from " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    selectors . append ( CSS : : Percentage ( 0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    read_a_selector  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( token . ident ( ) . equals_ignoring_ascii_case ( " to " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    selectors . append ( CSS : : Percentage ( 100 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    read_a_selector  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( token . is ( Token : : Type : : Percentage ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                selectors . append ( CSS : : Percentage ( token . percentage ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                read_a_selector  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( read_a_selector )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                child_tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( child_tokens . consume_a_token ( ) . is ( Token : : Type : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            child_tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        PropertiesAndCustomProperties  properties ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        qualified_rule . for_each_as_declaration_list ( [ & ] ( auto  const &  declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            extract_property ( declaration ,  properties ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  style  =  PropertyOwningCSSStyleDeclaration : : create ( m_context . realm ( ) ,  move ( properties . properties ) ,  move ( properties . custom_properties ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        for  ( auto &  selector  :  selectors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  keyframe_rule  =  CSSKeyframeRule : : create ( m_context . realm ( ) ,  selector ,  * style ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            keyframes . append ( keyframe_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  CSSKeyframesRule : : create ( m_context . realm ( ) ,  name ,  CSSRuleList : : create ( m_context . realm ( ) ,  move ( keyframes ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								GC : : Ptr < CSSNamespaceRule >  Parser : : convert_to_namespace_rule ( AtRule  const &  rule )  
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://drafts.csswg.org/css-namespaces/#syntax
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // @namespace <namespace-prefix>? [ <string> | <url> ] ;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // <namespace-prefix> = <ident>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( rule . prelude . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to parse @namespace rule: Empty prelude. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! rule . child_rules_and_lists_of_declarations . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to parse @namespace rule: Block is not allowed. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  tokens  =  TokenStream  {  rule . prelude  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < FlyString >  prefix  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( tokens . next_token ( ) . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        prefix  =  tokens . consume_a_token ( ) . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    FlyString  namespace_uri ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( auto  url  =  parse_url_function ( tokens ) ;  url . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-03 22:31:33 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        namespace_uri  =  url . value ( ) . to_string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    }  else  if  ( auto &  url_token  =  tokens . consume_a_token ( ) ;  url_token . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        namespace_uri  =  url_token . token ( ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to parse @namespace rule: Unable to parse `{}` as URL. " ,  tokens . next_token ( ) . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  constexpr  ( CSS_PARSER_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln ( " Failed to parse @namespace rule: Trailing tokens after URL. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tokens . dump_all_tokens ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  CSSNamespaceRule : : create ( m_context . realm ( ) ,  prefix ,  namespace_uri ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								GC : : Ptr < CSSSupportsRule >  Parser : : convert_to_supports_rule ( AtRule  const &  rule ,  Nested  nested )  
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://drafts.csswg.org/css-conditional-3/#at-supports
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // @supports <supports-condition> {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //   <rule-list>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( rule . prelude . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to parse @supports rule: Empty prelude. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  supports_tokens  =  TokenStream  {  rule . prelude  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  supports  =  parse_a_supports ( supports_tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! supports )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  constexpr  ( CSS_PARSER_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            dbgln ( " Failed to parse @supports rule: supports clause invalid. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            supports_tokens . dump_all_tokens ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-12-26 14:32:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    GC : : RootVector < CSSRule * >  child_rules  {  m_context . realm ( ) . heap ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-11-04 17:26:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto  const &  child  :  rule . child_rules_and_lists_of_declarations )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        child . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( Rule  const &  rule )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( auto  child_rule  =  convert_to_rule ( rule ,  nested ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    child_rules . append ( child_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            [ & ] ( Vector < Declaration >  const &  declarations )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto *  declaration  =  convert_to_style_declaration ( declarations ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: nested declarations invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                child_rules . append ( CSSNestedDeclarations : : create ( m_context . realm ( ) ,  * declaration ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  rule_list  =  CSSRuleList : : create ( m_context . realm ( ) ,  child_rules ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  CSSSupportsRule : : create ( m_context . realm ( ) ,  supports . release_nonnull ( ) ,  rule_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								GC : : Ptr < CSSPropertyRule >  Parser : : convert_to_property_rule ( AtRule  const &  rule )  
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://drafts.css-houdini.org/css-properties-values-api-1/#at-ruledef-property
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // @property <custom-property-name> {
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // <declaration-list>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // }
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( rule . prelude . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to parse @property rule: Empty prelude. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  prelude_stream  =  TokenStream  {  rule . prelude  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    prelude_stream . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  const &  token  =  prelude_stream . consume_a_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! token . is_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @property has invalid prelude, prelude = {}; discarding. " ,  rule . prelude ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  name_token  =  token . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    prelude_stream . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( prelude_stream . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @property has invalid prelude, prelude = {}; discarding. " ,  rule . prelude ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! name_token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @property name is invalid: {}; discarding. " ,  name_token . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! is_a_custom_property_name_string ( name_token . ident ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @property name doesn't start with '--': {}; discarding. " ,  name_token . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  const &  name  =  name_token . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < FlyString >  syntax_maybe ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < bool >  inherits_maybe ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < String >  initial_value_maybe ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rule . for_each_as_declaration_list ( [ & ] ( auto &  declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " syntax " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            token_stream . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  const &  syntax_token  =  token_stream . consume_a_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( syntax_token . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                token_stream . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( token_stream . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Unexpected trailing tokens in syntax " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    syntax_maybe  =  syntax_token . token ( ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Unexpected value for @property  \" syntax \" : {}; discarding. " ,  declaration . to_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " inherits " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            token_stream . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  const &  inherits_token  =  token_stream . consume_a_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( inherits_token . is_ident ( " true " sv )  | |  inherits_token . is_ident ( " false " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  const &  ident  =  inherits_token . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                token_stream . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( token_stream . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Unexpected trailing tokens in inherits " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    inherits_maybe  =  ( ident  = =  " true " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Expected true/false for @property  \" inherits \"  value, got: {}; discarding. " ,  inherits_token . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " initial-value " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // FIXME: Ensure that the initial value matches the syntax, and parse the correct CSSValue out
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            StringBuilder  initial_value_sb ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( auto  const &  component  :  declaration . value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                initial_value_sb . append ( component . to_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            initial_value_maybe  =  MUST ( initial_value_sb . to_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( syntax_maybe . has_value ( )  & &  inherits_maybe . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  CSSPropertyRule : : create ( m_context . realm ( ) ,  name ,  syntax_maybe . value ( ) ,  inherits_maybe . value ( ) ,  std : : move ( initial_value_maybe ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2024-11-15 04:01:23 +13:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								GC : : Ptr < CSSFontFaceRule >  Parser : : convert_to_font_face_rule ( AtRule  const &  rule )  
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://drafts.csswg.org/css-fonts/#font-face-rule
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < FlyString >  font_family ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < FlyString >  font_named_instance ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < ParsedFontFace : : Source >  src ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < Gfx : : UnicodeRange >  unicode_range ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < int >  weight ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < int >  slope ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < int >  width ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < Percentage >  ascent_override ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < Percentage >  descent_override ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < Percentage >  line_gap_override ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    FontDisplay  font_display  =  FontDisplay : : Auto ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < FlyString >  language_override ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < OrderedHashMap < FlyString ,  i64 > >  font_feature_settings ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Optional < OrderedHashMap < FlyString ,  double > >  font_variation_settings ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // "normal" is returned as nullptr
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  parse_as_percentage_or_normal  =  [ & ] ( Vector < ComponentValue >  const &  values )  - >  ErrorOr < Optional < Percentage > >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        // normal | <percentage [0,∞]>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        TokenStream  tokens  {  values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  percentage_value  =  parse_percentage_value ( tokens ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  Error : : from_string_literal ( " Unexpected trailing tokens " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( percentage_value - > is_percentage ( )  & &  percentage_value - > as_percentage ( ) . percentage ( ) . value ( )  > =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return  percentage_value - > as_percentage ( ) . percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // TODO: Once we implement calc-simplification in the parser, we should no longer see math values here,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //       unless they're impossible to resolve and thus invalid.
 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-11 15:05:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( percentage_value - > is_calculated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( auto  result  =  percentage_value - > as_calculated ( ) . resolve_percentage ( ) ;  result . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                    return  result . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Error : : from_string_literal ( " Invalid percentage " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ! tokens . consume_a_token ( ) . is_ident ( " normal " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Error : : from_string_literal ( " Expected `normal | <percentage [0,∞]>` " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        tokens . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  Error : : from_string_literal ( " Unexpected trailing tokens " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  OptionalNone  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    rule . for_each_as_declaration_list ( [ & ] ( auto &  declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " ascent-override " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  value  =  parse_as_percentage_or_normal ( declaration . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( value . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Failed to parse @font-face ascent-override: {} " ,  value . error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                ascent_override  =  value . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " descent-override " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  value  =  parse_as_percentage_or_normal ( declaration . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( value . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Failed to parse @font-face descent-override: {} " ,  value . error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                descent_override  =  value . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " font-display " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  keyword_value  =  parse_keyword_value ( token_stream ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                token_stream . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( token_stream . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Unexpected trailing tokens in font-display " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  value  =  keyword_to_font_display ( keyword_value - > to_keyword ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        font_display  =  * value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-13 13:51:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: `{}` is not a valid value for font-display " ,  keyword_value - > to_string ( CSSStyleValue : : SerializationMode : : Normal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " font-family " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // FIXME: This is very similar to, but different from, the logic in parse_font_family_value().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            //        Ideally they could share code.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Vector < FlyString >  font_family_parts ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            bool  had_syntax_error  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            for  ( size_t  i  =  0 ;  i  <  declaration . value . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  const &  part  =  declaration . value [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( part . is ( Token : : Type : : Whitespace ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( part . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( ! font_family_parts . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face font-family format invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        had_syntax_error  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    font_family_parts . append ( part . token ( ) . string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( part . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( is_css_wide_keyword ( part . token ( ) . ident ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face font-family format invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        had_syntax_error  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  keyword  =  keyword_from_string ( part . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    if  ( keyword . has_value ( )  & &  is_generic_font_family ( keyword . value ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face font-family format invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        had_syntax_error  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    font_family_parts . append ( part . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face font-family format invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                had_syntax_error  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( had_syntax_error  | |  font_family_parts . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            font_family  =  String : : join ( '   ' ,  font_family_parts ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " font-feature-settings " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  value  =  parse_css_value ( CSS : : PropertyID : : FontFeatureSettings ,  token_stream ) ;  ! value . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( value . value ( ) - > to_keyword ( )  = =  Keyword : : Normal )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    font_feature_settings . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( value . value ( ) - > is_value_list ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  const &  feature_tags  =  value . value ( ) - > as_value_list ( ) . values ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    OrderedHashMap < FlyString ,  i64 >  settings ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    settings . ensure_capacity ( feature_tags . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    for  ( auto  const &  feature_tag  :  feature_tags )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( ! feature_tag - > is_open_type_tagged ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Value in font-feature-settings descriptor is not an OpenTypeTaggedStyleValue; skipping " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        auto  const &  setting_value  =  feature_tag - > as_open_type_tagged ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( setting_value - > is_integer ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            settings . set ( feature_tag - > as_open_type_tagged ( ) . tag ( ) ,  setting_value - > as_integer ( ) . integer ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-11 15:05:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( setting_value - > is_calculated ( )  & &  setting_value - > as_calculated ( ) . resolves_to_number ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( auto  integer  =  setting_value - > as_calculated ( ) . resolve_integer ( ) ;  integer . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                                settings . set ( feature_tag - > as_open_type_tagged ( ) . tag ( ) ,  * integer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Calculated value in font-feature-settings descriptor cannot be resolved at parse time; skipping " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Value in font-feature-settings descriptor is not an OpenTypeTaggedStyleValue holding a <integer>; skipping " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    font_feature_settings  =  move ( settings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-13 13:51:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Failed to parse font-feature-settings descriptor, not compatible with value returned from parsing font-feature-settings property: {} " ,  value . value ( ) - > to_string ( CSSStyleValue : : SerializationMode : : Normal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " font-language-override " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  maybe_value  =  parse_css_value ( CSS : : PropertyID : : FontLanguageOverride ,  token_stream ) ;  ! maybe_value . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto &  value  =  maybe_value . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( value - > is_string ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    language_override  =  value - > as_string ( ) . string_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    language_override . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " font-named-instance " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            // auto | <string>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            token_stream . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  token  =  token_stream . consume_a_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            token_stream . discard_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( token_stream . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Unexpected trailing tokens in font-named-instance " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( token . is_ident ( " auto " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                font_named_instance . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  if  ( token . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                font_named_instance  =  token . token ( ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Failed to parse font-named-instance from {} " ,  token . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " font-style " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  value  =  parse_css_value ( CSS : : PropertyID : : FontStyle ,  token_stream ) ;  ! value . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                slope  =  value . value ( ) - > to_font_slope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " font-variation-settings " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  value  =  parse_css_value ( CSS : : PropertyID : : FontVariationSettings ,  token_stream ) ;  ! value . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( value . value ( ) - > to_keyword ( )  = =  Keyword : : Normal )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    font_variation_settings . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  if  ( value . value ( ) - > is_value_list ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  const &  variation_tags  =  value . value ( ) - > as_value_list ( ) . values ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    OrderedHashMap < FlyString ,  double >  settings ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    settings . ensure_capacity ( variation_tags . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    for  ( auto  const &  variation_tag  :  variation_tags )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( ! variation_tag - > is_open_type_tagged ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Value in font-variation-settings descriptor is not an OpenTypeTaggedStyleValue; skipping " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        auto  const &  setting_value  =  variation_tag - > as_open_type_tagged ( ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( setting_value - > is_number ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            settings . set ( variation_tag - > as_open_type_tagged ( ) . tag ( ) ,  setting_value - > as_number ( ) . number ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-11 15:05:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( setting_value - > is_calculated ( )  & &  setting_value - > as_calculated ( ) . resolves_to_number ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            if  ( auto  number  =  setting_value - > as_calculated ( ) . resolve_number ( ) ;  number . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                                settings . set ( variation_tag - > as_open_type_tagged ( ) . tag ( ) ,  * number ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Calculated value in font-variation-settings descriptor cannot be resolved at parse time; skipping " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Value in font-variation-settings descriptor is not an OpenTypeTaggedStyleValue holding a <number>; skipping " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    font_variation_settings  =  move ( settings ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2024-12-13 13:51:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Failed to parse font-variation-settings descriptor, not compatible with value returned from parsing font-variation-settings property: {} " ,  value . value ( ) - > to_string ( CSSStyleValue : : SerializationMode : : Normal ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2024-10-31 16:03:06 +00:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " font-weight " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  value  =  parse_css_value ( CSS : : PropertyID : : FontWeight ,  token_stream ) ;  ! value . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                weight  =  value . value ( ) - > to_font_weight ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " font-width " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            | |  declaration . name . equals_ignoring_ascii_case ( " font-stretch " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( auto  value  =  parse_css_value ( CSS : : PropertyID : : FontWidth ,  token_stream ) ;  ! value . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                width  =  value . value ( ) - > to_font_width ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " line-gap-override " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  value  =  parse_as_percentage_or_normal ( declaration . value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( value . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Failed to parse @font-face line-gap-override: {} " ,  value . error ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                line_gap_override  =  value . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " src " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            Vector < ParsedFontFace : : Source >  supported_sources  =  parse_font_face_src ( token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! supported_sources . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                src  =  move ( supported_sources ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( declaration . name . equals_ignoring_ascii_case ( " unicode-range " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            TokenStream  token_stream  {  declaration . value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  unicode_ranges  =  parse_unicode_ranges ( token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( unicode_ranges . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            unicode_range  =  move ( unicode_ranges ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Unrecognized descriptor '{}' in @font-face; discarding. " ,  declaration . name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! font_family . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Failed to parse @font-face: no font-family! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( unicode_range . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        unicode_range . empend ( 0x0u ,  0x10FFFFu ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  CSSFontFaceRule : : create ( m_context . realm ( ) ,  ParsedFontFace  {  font_family . release_value ( ) ,  move ( weight ) ,  move ( slope ) ,  move ( width ) ,  move ( src ) ,  move ( unicode_range ) ,  move ( ascent_override ) ,  move ( descent_override ) ,  move ( line_gap_override ) ,  font_display ,  move ( font_named_instance ) ,  move ( language_override ) ,  move ( font_feature_settings ) ,  move ( font_variation_settings )  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}