2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								/*
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2018 - 2020 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 11:55:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  Copyright  ( c )  2021 - 2022 ,  Sam  Atkins  < atkinssj @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2020-01-18 09:38:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 14:36:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  "GeneratorUtil.h" 
  
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <AK/SourceGenerator.h> 
  
						 
					
						
							
								
									
										
										
										
											2019-11-18 11:12:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								# include  <AK/StringBuilder.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-04-01 17:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibCore/ArgsParser.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-03-10 11:55:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibMain/Main.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:29:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 17:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ErrorOr < void >  generate_header_file ( JsonObject &  properties ,  Core : : Stream : : File &  file ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ErrorOr < void >  generate_implementation_file ( JsonObject &  properties ,  Core : : Stream : : File &  file ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-10 11:55:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								ErrorOr < int >  serenity_main ( Main : : Arguments  arguments )  
						 
					
						
							
								
									
										
										
										
											2019-11-18 11:12:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-01 17:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    StringView  generated_header_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringView  generated_implementation_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringView  properties_json_path ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Core : : ArgsParser  args_parser ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    args_parser . add_option ( generated_header_path ,  " Path to the PropertyID header file to generate " ,  " generated-header-path " ,  ' h ' ,  " generated-header-path " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    args_parser . add_option ( generated_implementation_path ,  " Path to the PropertyID implementation file to generate " ,  " generated-implementation-path " ,  ' c ' ,  " generated-implementation-path " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    args_parser . add_option ( properties_json_path ,  " Path to the JSON file to read from " ,  " json-path " ,  ' j ' ,  " json-path " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    args_parser . parse ( arguments ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 11:12:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 17:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  json  =  TRY ( read_entire_file_as_json ( properties_json_path ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-15 01:46:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    VERIFY ( json . is_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 17:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    auto  properties  =  json . as_object ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  generated_header_file  =  TRY ( Core : : Stream : : File : : open ( generated_header_path ,  Core : : Stream : : OpenMode : : Write ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  generated_implementation_file  =  TRY ( Core : : Stream : : File : : open ( generated_implementation_path ,  Core : : Stream : : OpenMode : : Write ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY ( generate_header_file ( properties ,  * generated_header_file ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY ( generate_implementation_file ( properties ,  * generated_implementation_file ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ErrorOr < void >  generate_header_file ( JsonObject &  properties ,  Core : : Stream : : File &  file )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    StringBuilder  builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SourceGenerator  generator  {  builder  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# pragma once 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <AK/NonnullRefPtr.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <AK/StringView.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <AK/Traits.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <LibWeb/Forward.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  Web : : CSS  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								enum  class  PropertyID  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Invalid , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Custom , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < String >  shorthand_property_ids ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    Vector < String >  longhand_property_ids ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( value . as_object ( ) . has ( " longhands " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 17:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            shorthand_property_ids . append ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            longhand_property_ids . append ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  first_property_id  =  shorthand_property_ids . first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  last_property_id  =  longhand_property_ids . last ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 11:12:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 17:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    for  ( auto &  name  :  shorthand_property_ids )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  member_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @ name : titlecase @ , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    for  ( auto &  name  :  longhand_property_ids )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  member_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    @ name : titlecase @ , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 17:26:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 17:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . set ( " first_property_id " ,  title_casify ( first_property_id ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . set ( " last_property_id " ,  title_casify ( last_property_id ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . set ( " first_shorthand_property_id " ,  title_casify ( shorthand_property_ids . first ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . set ( " last_shorthand_property_id " ,  title_casify ( shorthand_property_ids . last ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . set ( " first_longhand_property_id " ,  title_casify ( longhand_property_ids . first ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . set ( " last_longhand_property_id " ,  title_casify ( longhand_property_ids . last ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								PropertyID  property_id_from_camel_case_string ( StringView ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								PropertyID  property_id_from_string ( StringView ) ;  
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								StringView  string_from_property_id ( PropertyID ) ;  
						 
					
						
							
								
									
										
										
										
											2022-04-01 17:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  is_inherited_property ( PropertyID ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								NonnullRefPtr < StyleValue >  property_initial_value ( PropertyID ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  property_accepts_value ( PropertyID ,  StyleValue & ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								size_t  property_maximum_value_count ( PropertyID ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  property_affects_layout ( PropertyID ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  property_affects_stacking_context ( PropertyID ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								constexpr  PropertyID  first_property_id  =  PropertyID : : @ first_property_id @ ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								constexpr  PropertyID  last_property_id  =  PropertyID : : @ last_property_id @ ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								constexpr  PropertyID  first_shorthand_property_id  =  PropertyID : : @ first_shorthand_property_id @ ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								constexpr  PropertyID  last_shorthand_property_id  =  PropertyID : : @ last_shorthand_property_id @ ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								constexpr  PropertyID  first_longhand_property_id  =  PropertyID : : @ first_longhand_property_id @ ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								constexpr  PropertyID  last_longhand_property_id  =  PropertyID : : @ last_longhand_property_id @ ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								enum  class  Quirk  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    HashlessHexColor , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    // https://quirks.spec.whatwg.org/#the-unitless-length-quirk
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    UnitlessLength , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								bool  property_has_quirk ( PropertyID ,  Quirk ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  // namespace Web::CSS
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  AK  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								template < >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								struct  Traits < Web : : CSS : : PropertyID >  :  public  GenericTraits < Web : : CSS : : PropertyID >  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  unsigned  hash ( Web : : CSS : : PropertyID  property_id )  {  return  int_hash ( ( unsigned ) property_id ) ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								} ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  // namespace AK
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    TRY ( file . write ( generator . as_string_view ( ) . bytes ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								ErrorOr < void >  generate_implementation_file ( JsonObject &  properties ,  Core : : Stream : : File &  file )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    StringBuilder  builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    SourceGenerator  generator  {  builder  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								# include  <AK/Assertions.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-04-14 11:23:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/Enums.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-08-16 17:42:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/Parser/Parser.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/PropertyID.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-08-16 17:42:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								# include  <LibWeb/CSS/StyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								namespace  Web : : CSS  {  
						 
					
						
							
								
									
										
										
										
											2019-11-18 11:12:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:29:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								PropertyID  property_id_from_camel_case_string ( StringView  string )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  member_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . set ( " name " ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . set ( " name:camelcase " ,  camel_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( string . equals_ignoring_case ( " @name:camelcase@ " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  PropertyID : : @ name : titlecase @ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  PropertyID : : Invalid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:55:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								PropertyID  property_id_from_string ( StringView  string )  
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
									
										
										
										
											2019-11-18 11:12:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 17:26:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  member_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . set ( " name " ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( string . equals_ignoring_case ( " @name@ " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  PropertyID : : @ name : titlecase @ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
									
										
										
										
											2019-11-18 11:12:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  PropertyID : : Invalid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2019-11-18 11:12:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								StringView  string_from_property_id ( PropertyID  property_id )  {  
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    switch  ( property_id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
									
										
										
										
											2019-11-18 11:12:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 17:26:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-02-23 20:42:32 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  member_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . set ( " name " ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  PropertyID : : @ name : titlecase @ : 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  " @name@ " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-16 16:07:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
									
										
										
										
											2019-11-18 11:12:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  " (invalid CSS::PropertyID) " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-16 16:07:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  is_inherited_property ( PropertyID  property_id )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( property_id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 17:26:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-16 16:07:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  inherited  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( value . as_object ( ) . has ( " inherited " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  inherited_value  =  value . as_object ( ) . get ( " inherited " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-16 16:07:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( inherited_value . is_bool ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            inherited  =  inherited_value . as_bool ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( inherited )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  member_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            member_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            member_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  PropertyID : : @ name : titlecase @ : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 17:46:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  property_affects_layout ( PropertyID  property_id )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( property_id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        bool  affects_layout  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( value . as_object ( ) . has ( " affects-layout " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            affects_layout  =  value . as_object ( ) . get ( " affects-layout " sv ) . to_bool ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-16 17:46:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( affects_layout )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  member_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            member_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            member_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  PropertyID : : @ name : titlecase @ : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 10:58:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  property_affects_stacking_context ( PropertyID  property_id )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( property_id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-25 00:59:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bool  affects_stacking_context  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( value . as_object ( ) . has ( " affects-stacking-context " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            affects_stacking_context  =  value . as_object ( ) . get ( " affects-stacking-context " sv ) . to_bool ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 10:58:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-25 00:59:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( affects_stacking_context )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 10:58:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  member_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            member_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            member_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  PropertyID : : @ name : titlecase @ : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-10 13:54:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								NonnullRefPtr < StyleValue >  property_initial_value ( PropertyID  property_id )  
						 
					
						
							
								
									
										
										
										
											2021-08-16 17:42:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:15:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    static  Array < RefPtr < StyleValue > ,  to_underlying ( last_property_id )  +  1 >  initial_values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    static  bool  initialized  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    if  ( ! initialized )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        initialized  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 12:00:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        Parser : : ParsingContext  parsing_context ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-16 17:42:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate shorthand initial values after their longhands
When parsing shorthand values, we'd like to use
`property_initial_value()` to get their longhand property values,
instead of hard-coding them as we currently do. That involves
recursively calling that function while the `initial_values` map is
being initialized, which causes problems because the shorthands appear
alphabetically before their longhand components, so the longhands aren't
initialized yet!
The solution here is to perform 2 passes when generating the code,
outputting properties without "longhands" first, and the rest after.
This could potentially cause issues when shorthands have multiple
levels, in particular `border` -> `border-color` -> `border-left-color`.
But, we do not currently define a default value for `border`, and
`border-color` takes only a single value, so it's fine for now. :^)
											 
										 
										
											2021-09-17 16:53:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    // NOTE: Parsing a shorthand property requires that its longhands are already available here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //       So, we do this in two passes: First longhands, then shorthands.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //       Probably we should build a dependency graph and then handle them in order, but this
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    //       works for now! :^)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    auto  output_initial_value_code  =  [ & ] ( auto &  name ,  auto &  object )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! object . has ( " initial " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-10 13:48:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            dbgln ( " No initial value specified for property '{}' " ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto &  initial_value  =  object . get ( " initial " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-10 13:48:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        VERIFY ( initial_value . is_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  initial_value_string  =  initial_value . as_string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-16 17:42:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-10 13:48:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        auto  member_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . set ( " initial_value_string " ,  initial_value_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        member_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  parsed_value  =  parse_css_value ( parsing_context ,  " @initial_value_string@ " sv ,  PropertyID : : @ name : titlecase @ ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-10 13:48:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( ! parsed_value . is_null ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:15:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            initial_values [ to_underlying ( PropertyID : : @ name : titlecase @ ) ]  =  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-16 17:42:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-10 13:48:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate shorthand initial values after their longhands
When parsing shorthand values, we'd like to use
`property_initial_value()` to get their longhand property values,
instead of hard-coding them as we currently do. That involves
recursively calling that function while the `initial_values` map is
being initialized, which causes problems because the shorthands appear
alphabetically before their longhand components, so the longhands aren't
initialized yet!
The solution here is to perform 2 passes when generating the code,
outputting properties without "longhands" first, and the rest after.
This could potentially cause issues when shorthands have multiple
levels, in particular `border` -> `border-color` -> `border-left-color`.
But, we do not currently define a default value for `border`, and
`border-color` takes only a single value, so it's fine for now. :^)
											 
										 
										
											2021-09-17 16:53:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( value . as_object ( ) . has ( " longhands " sv ) ) 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate shorthand initial values after their longhands
When parsing shorthand values, we'd like to use
`property_initial_value()` to get their longhand property values,
instead of hard-coding them as we currently do. That involves
recursively calling that function while the `initial_values` map is
being initialized, which causes problems because the shorthands appear
alphabetically before their longhand components, so the longhands aren't
initialized yet!
The solution here is to perform 2 passes when generating the code,
outputting properties without "longhands" first, and the rest after.
This could potentially cause issues when shorthands have multiple
levels, in particular `border` -> `border-color` -> `border-left-color`.
But, we do not currently define a default value for `border`, and
`border-color` takes only a single value, so it's fine for now. :^)
											 
										 
										
											2021-09-17 16:53:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        output_initial_value_code ( name ,  value . as_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( ! value . as_object ( ) . has ( " longhands " sv ) ) 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate shorthand initial values after their longhands
When parsing shorthand values, we'd like to use
`property_initial_value()` to get their longhand property values,
instead of hard-coding them as we currently do. That involves
recursively calling that function while the `initial_values` map is
being initialized, which causes problems because the shorthands appear
alphabetically before their longhand components, so the longhands aren't
initialized yet!
The solution here is to perform 2 passes when generating the code,
outputting properties without "longhands" first, and the rest after.
This could potentially cause issues when shorthands have multiple
levels, in particular `border` -> `border-color` -> `border-left-color`.
But, we do not currently define a default value for `border`, and
`border-color` takes only a single value, so it's fine for now. :^)
											 
										 
										
											2021-09-17 16:53:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        output_initial_value_code ( name ,  value . as_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-16 17:42:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate shorthand initial values after their longhands
When parsing shorthand values, we'd like to use
`property_initial_value()` to get their longhand property values,
instead of hard-coding them as we currently do. That involves
recursively calling that function while the `initial_values` map is
being initialized, which causes problems because the shorthands appear
alphabetically before their longhand components, so the longhands aren't
initialized yet!
The solution here is to perform 2 passes when generating the code,
outputting properties without "longhands" first, and the rest after.
This could potentially cause issues when shorthands have multiple
levels, in particular `border` -> `border-color` -> `border-left-color`.
But, we do not currently define a default value for `border`, and
`border-color` takes only a single value, so it's fine for now. :^)
											 
										 
										
											2021-09-17 16:53:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:15:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    return  * initial_values [ to_underlying ( property_id ) ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-16 17:42:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 17:26:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  property_has_quirk ( PropertyID  property_id ,  Quirk  quirk )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( property_id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( value . as_object ( ) . has ( " quirks " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  quirks_value  =  value . as_object ( ) . get ( " quirks " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 17:26:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( quirks_value . is_array ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto &  quirks  =  quirks_value . as_array ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( ! quirks . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  property_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                property_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                property_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  PropertyID : : @ name : titlecase @ :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        switch  ( quirk )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                for  ( auto &  quirk  :  quirks . values ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    VERIFY ( quirk . is_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    auto  quirk_generator  =  property_generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    quirk_generator . set ( " quirk:titlecase " ,  title_casify ( quirk . as_string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    quirk_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  Quirk : : @ quirk : titlecase @ : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                property_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								bool  property_accepts_value ( PropertyID  property_id ,  StyleValue &  style_value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-12-03 20:17:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    if  ( style_value . is_builtin ( ) ) 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( property_id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto &  object  =  value . as_object ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        bool  has_valid_types  =  object . has ( " valid-types " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        auto  has_valid_identifiers  =  object . has ( " valid-identifiers " sv ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( has_valid_types  | |  has_valid_identifiers )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  property_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  PropertyID : : @ name : titlecase @ :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-26 14:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            auto  output_numeric_value_check  =  [ ] ( SourceGenerator &  generator ,  StringView  type_check_function ,  StringView  value_getter ,  Span < StringView >  resolved_type_names ,  StringView  min_value ,  StringView  max_value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  test_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                test_generator . set ( " type_check_function " ,  type_check_function ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                test_generator . set ( " value_getter " ,  value_getter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                test_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( ( style_value . @ type_check_function @ ( ) ) ~ ~ ~ " ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! min_value . is_empty ( )  & &  min_value  ! =  " -∞ " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    test_generator . set ( " minvalue " ,  min_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    test_generator . append ( "  && (style_value.@value_getter@ >= @minvalue@) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! max_value . is_empty ( )  & &  max_value  ! =  " ∞ " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    test_generator . set ( " maxvalue " ,  max_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    test_generator . append ( "  && (style_value.@value_getter@ <= @maxvalue@) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                test_generator . append ( " ) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! resolved_type_names . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    test_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        | |  ( style_value . is_calculated ( )  & &  ( ) ~ ~ ~ " ); 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    bool  first  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    for  ( auto &  type_name  :  resolved_type_names )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        test_generator . set ( " resolved_type_name " ,  type_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( ! first ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            test_generator . append ( "  ||  " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        test_generator . append ( " style_value.as_calculated().resolved_type() == CalculatedStyleValue::ResolvedType::@resolved_type_name@ " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        first  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    test_generator . append ( " )) " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                test_generator . append ( R " ~~~() { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            if  ( has_valid_types )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  valid_types_value  =  object . get ( " valid-types " sv ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                VERIFY ( valid_types_value . is_array ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  valid_types  =  valid_types_value . as_array ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! valid_types . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    for  ( auto &  type  :  valid_types . values ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        VERIFY ( type . is_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-23 12:45:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        auto  type_parts  =  type . as_string ( ) . split_view ( '   ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        auto  type_name  =  type_parts . first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        auto  type_args  =  type_parts . size ( )  >  1  ?  type_parts [ 1 ]  :  " " sv ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-26 14:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        StringView  min_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        StringView  max_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        if  ( ! type_args . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            VERIFY ( type_args . starts_with ( ' [ ' )  & &  type_args . ends_with ( ' ] ' ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            auto  comma_index  =  type_args . find ( ' , ' ) . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            min_value  =  type_args . substring_view ( 1 ,  comma_index  -  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            max_value  =  type_args . substring_view ( comma_index  +  1 ,  type_args . length ( )  -  comma_index  -  2 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 13:49:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        if  ( type_name  = =  " angle " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            output_numeric_value_check ( property_generator ,  " is_angle " sv ,  " as_angle().angle().to_degrees() " sv ,  Array  {  " Angle " sv  } ,  min_value ,  max_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 13:49:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " color " )  { 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            property_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-23 19:54:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( style_value . has_color ( ) ) 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 13:49:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " frequency " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            output_numeric_value_check ( property_generator ,  " is_frequency " sv ,  " as_frequency().frequency().to_hertz() " sv ,  Array  {  " Frequency " sv  } ,  min_value ,  max_value ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " image " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            property_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( style_value . is_abstract_image ( ) ) 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
									
										
										
										
											2022-03-26 14:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " integer " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            output_numeric_value_check ( property_generator ,  " has_integer " sv ,  " to_integer() " sv ,  Array  {  " Integer " sv  } ,  min_value ,  max_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-19 16:07:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " length " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            output_numeric_value_check ( property_generator ,  " has_length " sv ,  " to_length().raw_value() " sv ,  Array  {  " Length " sv  } ,  min_value ,  max_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-26 14:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " number " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            output_numeric_value_check ( property_generator ,  " has_number " sv ,  " to_number() " sv ,  Array  {  " Integer " sv ,  " Number " sv  } ,  min_value ,  max_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 13:49:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " percentage " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            output_numeric_value_check ( property_generator ,  " is_percentage " sv ,  " as_percentage().percentage().value() " sv ,  Array  {  " Percentage " sv  } ,  min_value ,  max_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " rect " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            property_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( style_value . has_rect ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
									
										
										
										
											2022-02-22 13:49:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " resolution " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            output_numeric_value_check ( property_generator ,  " is_resolution " sv ,  " as_resolution().resolution().to_dots_per_pixel() " sv ,  Array < StringView ,  0 >  { } ,  min_value ,  max_value ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " string " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            property_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( style_value . is_string ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 13:49:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " time " )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            output_numeric_value_check ( property_generator ,  " is_time " sv ,  " as_time().time().to_seconds() " sv ,  Array  {  " Time " sv  } ,  min_value ,  max_value ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        }  else  if  ( type_name  = =  " url " )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            // FIXME: Handle urls!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 11:23:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                            // Assume that any other type names are defined in Enums.json.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            // If they're not, the output won't compile, but that's fine since it's invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            property_generator . set ( " type_name:snakecase " ,  snake_casify ( type_name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                            property_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        if  ( auto  converted_identifier  =  value_id_to_ @ type_name : snakecase @ ( style_value . to_identifier ( ) ) ;  converted_identifier . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            if  ( has_valid_identifiers )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                auto  valid_identifiers_value  =  object . get ( " valid-identifiers " sv ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Generate property_accepts_value() function :^)
Previously, we have not been validating the values for CSS declarations
inside the Parser. This causes issues, since we should be discarding
invalid style declarations, so that previous ones are used instead. For
example, in this code:
```css
.foo {
  width: 2em;
  width: orange;
}
```
... the `width: orange` declaration overwrites the `width: 2em` one,
even though it is invalid. According to the spec, `width: orange` should
be rejected at parse time, and discarded, leaving `width: 2em` as the
resulting value.
Many properties (mostly shorthands) are parsed specially, and so they
are already rejected if they are invalid. But for simple properties, we
currently accept any value. With `property_accepts_value()`, we can
check if the value is valid in `parse_css_value()`, and reject it if it
is not.
											 
										 
										
											2021-09-22 20:11:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								                VERIFY ( valid_identifiers_value . is_array ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                auto  valid_identifiers  =  valid_identifiers_value . as_array ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                if  ( ! valid_identifiers . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    property_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        switch  ( style_value . to_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    for  ( auto &  identifier  :  valid_identifiers . values ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        VERIFY ( identifier . is_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        auto  identifier_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        identifier_generator . set ( " identifier:titlecase " ,  title_casify ( identifier . as_string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                        identifier_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        case  ValueID : : @ identifier : titlecase @ : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                    property_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								size_t  property_maximum_value_count ( PropertyID  property_id )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    switch  ( property_id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    properties . for_each_member ( [ & ] ( auto &  name ,  auto &  value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        VERIFY ( value . is_object ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								        if  ( value . as_object ( ) . has ( " max-values " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  max_values  =  value . as_object ( ) . get ( " max-values " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 12:24:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								            VERIFY ( max_values . is_number ( )  & &  ! max_values . is_double ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            auto  property_generator  =  generator . fork ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_generator . set ( " name:titlecase " ,  title_casify ( name ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_generator . set ( " max_values " ,  max_values . to_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								            property_generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    case  PropertyID : : @ name : titlecase @ : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  @ max_values @ ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    generator . append ( R " ~~~( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								        return  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  // namespace Web::CSS
  
						 
					
						
							
								
									
										
										
										
											2021-04-05 10:12:37 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2020-10-23 18:37:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								) ~ ~ ~ " );  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 17:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								    TRY ( file . write ( generator . as_string_view ( ) . bytes ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-18 11:12:58 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}