2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								/*
  
						 
					
						
							
								
									
										
										
										
											2022-03-26 14:21:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2018 - 2022 ,  Andreas  Kling  < kling @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-28 22:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2020 - 2021 ,  the  SerenityOS  developers . 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 17:17:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2021 - 2023 ,  Sam  Atkins  < atkinssj @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 21:28:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2021 ,  Tobias  Christiansen  < tobyase @ serenityos . org > 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  Copyright  ( c )  2022 ,  MacDue  < macdue @ dueutil . tech > 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 * 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-22 01:24:48 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								 *  SPDX - License - Identifier :  BSD - 2 - Clause 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								 */ 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/CharacterTypes.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-07-23 13:06:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/Debug.h> 
  
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/GenericLexer.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-04-24 20:20:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <AK/SourceLocation.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/CSSFontFaceRule.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-30 22:57:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/CSSImportRule.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-05-26 23:30:54 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/CSSKeyframeRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/CSSKeyframesRule.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-09-29 15:51:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/CSSMediaRule.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-07-09 16:34:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/CSSStyleDeclaration.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/CSSStyleRule.h> 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/CSSStyleSheet.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-10-08 17:48:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/CSSSupportsRule.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-30 15:33:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/CalculatedOr.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-30 14:22:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/EdgeRect.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-10-23 21:05:34 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/MediaList.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-04-12 14:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/Parser/Block.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/Parser/ComponentValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/Parser/DeclarationOrAtRule.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-04-12 13:35:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/Parser/Function.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/Parser/Parser.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/Parser/Rule.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/Selector.h> 
  
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 17:26:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/AngleStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 17:44:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/BackgroundRepeatStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 17:54:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/BackgroundSizeStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 17:35:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/BackgroundStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-25 00:29:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/BorderRadiusShorthandStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-25 00:33:20 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/BorderRadiusStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 20:56:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/BorderStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 21:12:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/ColorStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-05-26 23:16:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/CompositeStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 16:09:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/ConicGradientStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 21:17:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/ContentStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-05-25 12:43:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/CustomIdentStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/DisplayStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-07-06 02:29:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/EasingStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/EdgeStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 21:26:03 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/FilterValueListStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 21:39:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/FlexFlowStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 21:33:13 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/FlexStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 21:44:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/FontStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-23 21:50:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/FrequencyStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 14:48:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/GridAreaShorthandStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 14:25:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/GridTemplateAreaStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 14:50:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/GridTrackPlacementShorthandStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 14:53:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/GridTrackPlacementStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-04-29 19:32:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/GridTrackSizeListShorthandStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-04-29 17:59:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/GridTrackSizeListStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 15:04:24 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/IdentifierStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 15:17:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/ImageStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 16:45:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/InheritStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 16:55:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/InitialStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:01:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/IntegerStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 17:04:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/LengthStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 16:17:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/LinearGradientStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 17:07:57 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/ListStyleStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-06-01 16:16:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/NumberStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 17:20:16 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/OverflowStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 17:28:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/PercentageStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-05-29 16:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/PlaceContentStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 17:35:31 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/PositionStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 16:35:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/RadialGradientStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-06-06 15:42:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/RatioStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-25 00:02:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/RectStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 17:40:28 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/ResolutionStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 17:45:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/ShadowStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 17:48:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/StringStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-25 00:12:21 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/StyleValueList.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 17:52:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/TextDecorationStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 23:47:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/TimeStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 17:59:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/TransformationStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-04-21 18:31:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/URLStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 23:53:41 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/UnresolvedStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-03-24 23:56:56 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/CSS/StyleValues/UnsetStyleValue.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-04-29 21:16:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Dump.h> 
  
						 
					
						
							
								
									
										
										
										
											2023-02-17 15:21:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# include  <LibWeb/Infra/Strings.h> 
  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-01 20:58:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  void  log_parse_error ( SourceLocation  const &  location  =  SourceLocation : : current ( ) )  
						 
					
						
							
								
									
										
										
										
											2021-04-24 20:20:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-23 13:06:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    dbgln_if ( CSS_PARSER_DEBUG ,  " Parse error (CSS) {} " ,  location ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-24 20:20:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 12:00:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								namespace  Web : : CSS : : Parser  {  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 17:17:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < Parser >  Parser : : create ( ParsingContext  const &  context ,  StringView  input ,  StringView  encoding )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TRY ( Tokenizer : : tokenize ( input ,  encoding ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  Parser  {  context ,  move ( tokens )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Parser : : Parser ( ParsingContext  const &  context ,  Vector < Token >  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 14:00:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    :  m_context ( context ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 17:17:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    ,  m_tokens ( move ( tokens ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    ,  m_token_stream ( m_tokens ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Parser : : Parser ( Parser & &  other )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    :  m_context ( other . m_context ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    ,  m_tokens ( move ( other . m_tokens ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    ,  m_token_stream ( m_tokens ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 14:00:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-03-06 17:17:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Moving the TokenStream directly from `other` would break it, because TokenStream holds
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // a reference to the Vector<Token>, so it would be pointing at the old Parser's tokens.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // So instead, we create a new TokenStream from this Parser's tokens, and then tell it to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // copy the other TokenStream's state. This is quite hacky.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    m_token_stream . copy_state ( { } ,  other . m_token_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 14:00:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:51:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.3.3. Parse a stylesheet
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#parse-stylesheet
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-03-29 14:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Parser : : ParsedStyleSheet  Parser : : parse_a_stylesheet ( TokenStream < T > &  tokens ,  Optional < AK : : URL >  location )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:51:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To parse a stylesheet from an input given an optional url location:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. If input is a byte stream for stylesheet, decode bytes from input, and set input to the result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Normalize input, and set input to the result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: These are done automatically when creating the Parser.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Create a new stylesheet, with its location set to location (or null, if location was not passed).
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 14:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    ParsedStyleSheet  style_sheet ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    style_sheet . location  =  move ( location ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:51:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 4. Consume a list of rules from input, with the top-level flag set, and set the stylesheet’  
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 14:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    style_sheet . rules  =  consume_a_list_of_rules ( tokens ,  TopLevel : : Yes ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 14:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. Return the stylesheet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  style_sheet ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#parse-a-css-stylesheet
  
						 
					
						
							
								
									
										
										
										
											2022-08-07 13:14:54 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								CSSStyleSheet *  Parser : : parse_as_css_stylesheet ( Optional < AK : : URL >  location )  
						 
					
						
							
								
									
										
										
										
											2022-03-29 14:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To parse a CSS stylesheet, first parse a stylesheet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  style_sheet  =  parse_a_stylesheet ( m_token_stream ,  { } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Interpret all of the resulting top-level qualified rules as style rules, defined below.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-24 16:34:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    JS : : MarkedVector < CSSRule * >  rules ( m_context . realm ( ) . heap ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 14:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  raw_rule  :  style_sheet . rules )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 15:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto *  rule  =  convert_to_rule ( raw_rule ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 14:13:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								        // If any style rule is invalid, or any at-rule is not recognized or is invalid according to its grammar or context, it’  
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 12:34:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( rule ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 15:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            rules . append ( rule ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 12:34:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 23:03:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  rule_list  =  CSSRuleList : : create ( m_context . realm ( ) ,  rules ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-13 10:50:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  media_list  =  MediaList : : create ( m_context . realm ( ) ,  { } ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  CSSStyleSheet : : create ( m_context . realm ( ) ,  rule_list ,  media_list ,  move ( location ) ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 12:34:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 15:14:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < SelectorList >  Parser : : parse_as_selector ( SelectorParsingMode  parsing_mode )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 12:34:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:29:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  selector_list  =  parse_a_selector_list ( m_token_stream ,  SelectorType : : Standalone ,  parsing_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 17:42:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! selector_list . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  selector_list . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 12:34:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 15:14:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < SelectorList >  Parser : : parse_as_relative_selector ( SelectorParsingMode  parsing_mode )  
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:29:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  selector_list  =  parse_a_selector_list ( m_token_stream ,  SelectorType : : Relative ,  parsing_mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 17:42:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! selector_list . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  selector_list . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Parser : : ParseErrorOr < SelectorList >  Parser : : parse_a_selector_list ( TokenStream < T > &  tokens ,  SelectorType  mode ,  SelectorParsingMode  parsing_mode )  
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-30 17:06:48 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  comma_separated_lists  =  parse_a_comma_separated_list_of_component_values ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 12:34:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < NonnullRefPtr < Selector > >  selectors ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  selector_parts  :  comma_separated_lists )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  stream  =  TokenStream ( selector_parts ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:29:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  selector  =  parse_complex_selector ( stream ,  mode ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 15:14:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( selector . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( parsing_mode  = =  SelectorParsingMode : : Forgiving ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 17:42:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  selector . error ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 15:14:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 17:42:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        selectors . append ( selector . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 15:14:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( selectors . is_empty ( )  & &  parsing_mode  ! =  SelectorParsingMode : : Forgiving ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  selectors ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Parser : : ParseErrorOr < NonnullRefPtr < Selector > >  Parser : : parse_complex_selector ( TokenStream < ComponentValue > &  tokens ,  SelectorType  mode )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 12:34:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Selector : : CompoundSelector >  compound_selectors ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 21:16:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  first_selector  =  TRY ( parse_compound_selector ( tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! first_selector . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 19:29:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( mode  = =  SelectorType : : Standalone )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first_selector - > combinator  ! =  Selector : : Combinator : : Descendant ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        first_selector - > combinator  =  Selector : : Combinator : : None ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    compound_selectors . append ( first_selector . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 17:47:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  compound_selector  =  TRY ( parse_compound_selector ( tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! compound_selector . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        compound_selectors . append ( compound_selector . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-07 17:47:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( compound_selectors . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 21:16:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  Selector : : create ( move ( compound_selectors ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-06-30 16:27:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Parser : : ParseErrorOr < Optional < Selector : : CompoundSelector > >  Parser : : parse_compound_selector ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-30 16:27:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  combinator  =  parse_selector_combinator ( tokens ) . value_or ( Selector : : Combinator : : Descendant ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 21:16:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-06-30 16:27:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Selector : : SimpleSelector >  simple_selectors ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 14:54:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  component  =  TRY ( parse_simple_selector ( tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! component . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        simple_selectors . append ( component . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( simple_selectors . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Optional < Selector : : CompoundSelector >  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 21:16:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  Selector : : CompoundSelector  {  combinator ,  move ( simple_selectors )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-04-29 21:16:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Selector : : Combinator >  Parser : : parse_selector_combinator ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:34:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  current_value  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( current_value . is ( Token : : Type : : Delim ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( current_value . token ( ) . delim ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' > ' : 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : Combinator : : ImmediateChild ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' + ' : 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : Combinator : : NextSibling ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' ~ ' : 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : Combinator : : SubsequentSibling ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' | ' :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:34:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  next  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( next . is ( Token : : Type : : EndOfFile ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 14:54:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( next . is_delim ( ' | ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Selector : : Combinator : : Column ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 14:54:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 14:54:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Parser : : ParseErrorOr < Selector : : SimpleSelector >  Parser : : parse_attribute_simple_selector ( ComponentValue  const &  first_value )  
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  attribute_tokens  =  TokenStream  {  first_value . block ( ) . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    attribute_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! attribute_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSS attribute selector is empty! " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Handle namespace prefix for attribute name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  attribute_part  =  attribute_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! attribute_part . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Expected ident for attribute name, got: '{}' " ,  attribute_part . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Selector : : SimpleSelector  simple_selector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        . type  =  Selector : : SimpleSelector : : Type : : Attribute , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        . value  =  Selector : : SimpleSelector : : Attribute  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            . match_type  =  Selector : : SimpleSelector : : Attribute : : MatchType : : HasAttribute , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: Case-sensitivity is defined by the document language.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // HTML is insensitive with attribute names, and our code generally assumes
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // they are converted to lowercase, so we do that here too. If we want to be
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // correct with XML later, we'll need to keep the original case and then do
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // a case-insensitive compare later.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-09 18:07:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            . name  =  FlyString : : from_deprecated_fly_string ( attribute_part . token ( ) . ident ( ) . to_lowercase_string ( ) ) . release_value_but_fixme_should_propagate_errors ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            . case_type  =  Selector : : SimpleSelector : : Attribute : : CaseType : : DefaultMatch , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    attribute_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! attribute_tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  simple_selector ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  delim_part  =  attribute_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! delim_part . is ( Token : : Type : : Delim ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Expected a delim for attribute comparison, got: '{}' " ,  delim_part . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( delim_part . token ( ) . delim ( )  = =  ' = ' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        simple_selector . attribute ( ) . match_type  =  Selector : : SimpleSelector : : Attribute : : MatchType : : ExactValueMatch ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! attribute_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Attribute selector ended part way through a match type. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  delim_second_part  =  attribute_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! delim_second_part . is_delim ( ' = ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Expected a double delim for attribute comparison, got: '{}{}' " ,  delim_part . to_debug_string ( ) ,  delim_second_part . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( delim_part . token ( ) . delim ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' ~ ' : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            simple_selector . attribute ( ) . match_type  =  Selector : : SimpleSelector : : Attribute : : MatchType : : ContainsWord ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' * ' : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            simple_selector . attribute ( ) . match_type  =  Selector : : SimpleSelector : : Attribute : : MatchType : : ContainsString ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' | ' : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            simple_selector . attribute ( ) . match_type  =  Selector : : SimpleSelector : : Attribute : : MatchType : : StartsWithSegment ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' ^ ' : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            simple_selector . attribute ( ) . match_type  =  Selector : : SimpleSelector : : Attribute : : MatchType : : StartsWithString ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' $ ' : 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 15:43:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            simple_selector . attribute ( ) . match_type  =  Selector : : SimpleSelector : : Attribute : : MatchType : : EndsWithString ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            attribute_tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    attribute_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! attribute_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Attribute selector ended without a value to match. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  value_part  =  attribute_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! value_part . is ( Token : : Type : : Ident )  & &  ! value_part . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Expected a string or ident for the value to match attribute against, got: '{}' " ,  value_part . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:42:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  value_string_view  =  value_part . token ( ) . is ( Token : : Type : : Ident )  ?  value_part . token ( ) . ident ( )  :  value_part . token ( ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    simple_selector . attribute ( ) . value  =  String : : from_utf8 ( value_string_view ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    attribute_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Handle case-sensitivity suffixes. https://www.w3.org/TR/selectors-4/#attribute-case
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( attribute_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  case_sensitivity_part  =  attribute_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( case_sensitivity_part . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  case_sensitivity  =  case_sensitivity_part . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( case_sensitivity . equals_ignoring_ascii_case ( " i " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                simple_selector . attribute ( ) . case_type  =  Selector : : SimpleSelector : : Attribute : : CaseType : : CaseInsensitiveMatch ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( case_sensitivity . equals_ignoring_ascii_case ( " s " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                simple_selector . attribute ( ) . case_type  =  Selector : : SimpleSelector : : Attribute : : CaseType : : CaseSensitiveMatch ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " Expected a  \" i \"  or  \" s \"  attribute selector case sensitivity identifier, got: '{}' " ,  case_sensitivity_part . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Expected an attribute selector case sensitivity identifier, got: '{}' " ,  case_sensitivity_part . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( attribute_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Was not expecting anything else inside attribute selector. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 18:01:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  simple_selector ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Parser : : ParseErrorOr < Selector : : SimpleSelector >  Parser : : parse_pseudo_simple_selector ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  peek_token_ends_selector  =  [ & ] ( )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  value  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ( value . is ( Token : : Type : : EndOfFile )  | |  value . is ( Token : : Type : : Whitespace )  | |  value . is ( Token : : Type : : Comma ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( peek_token_ends_selector ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  is_pseudo  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . peek_token ( ) . is ( Token : : Type : : Colon ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        is_pseudo  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( peek_token_ends_selector ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_pseudo )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  name_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! name_token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Expected an ident for pseudo-element, got: '{}' " ,  name_token . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  pseudo_name  =  name_token . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-22 15:58:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  pseudo_element  =  pseudo_element_from_string ( pseudo_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Note: We allow the "ignored" -webkit prefix here for -webkit-progress-bar/-webkit-progress-bar
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! pseudo_element . has_value ( )  & &  has_ignored_vendor_prefix ( pseudo_name ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : IncludesIgnoredVendorPrefix ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! pseudo_element . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Unrecognized pseudo-element: '::{}' " ,  pseudo_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            . type  =  Selector : : SimpleSelector : : Type : : PseudoElement , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            . value  =  pseudo_element . value ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( peek_token_ends_selector ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  pseudo_class_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( pseudo_class_token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  pseudo_name  =  pseudo_class_token . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( has_ignored_vendor_prefix ( pseudo_name ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : IncludesIgnoredVendorPrefix ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  make_pseudo_class_selector  =  [ ] ( auto  pseudo_class )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . type  =  Selector : : SimpleSelector : : Type : : PseudoClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . value  =  Selector : : SimpleSelector : : PseudoClass  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    . type  =  pseudo_class  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " active " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Active ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " checked " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Checked ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-20 04:35:43 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " indeterminate " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Indeterminate ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-29 23:48:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " defined " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Defined ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " disabled " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Disabled ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " empty " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Empty ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " enabled " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Enabled ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " first-child " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : FirstChild ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " first-of-type " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : FirstOfType ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " focus " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Focus ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " focus-within " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : FocusWithin ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " hover " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Hover ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " last-child " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : LastChild ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " last-of-type " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : LastOfType ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " link " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Link ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " only-child " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : OnlyChild ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " only-of-type " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : OnlyOfType ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " root " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Root ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-05 11:43:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " host " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Host ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " visited " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Visited ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-20 23:42:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_name . equals_ignoring_ascii_case ( " scope " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_pseudo_class_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : Scope ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Single-colon syntax allowed for ::after, ::before, ::first-letter and ::first-line for compatibility.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://www.w3.org/TR/selectors/#pseudo-element-syntax
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  pseudo_element  =  pseudo_element_from_string ( pseudo_name ) ;  pseudo_element . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            switch  ( pseudo_element . value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : PseudoElement : : After : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : PseudoElement : : Before : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : PseudoElement : : FirstLetter : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  Selector : : PseudoElement : : FirstLine : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    . type  =  Selector : : SimpleSelector : : Type : : PseudoElement , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    . value  =  pseudo_element . value ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Unrecognized pseudo-class: ':{}' " ,  pseudo_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( pseudo_class_token . is_function ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  parse_nth_child_selector  =  [ this ] ( auto  pseudo_class ,  Vector < ComponentValue >  const &  function_values ,  bool  allow_of  =  false )  - >  ParseErrorOr < Selector : : SimpleSelector >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  tokens  =  TokenStream < ComponentValue > ( function_values ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  nth_child_pattern  =  parse_a_n_plus_b_pattern ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! nth_child_pattern . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " !!! Invalid An+B format for {} " ,  pseudo_class_name ( pseudo_class ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    . type  =  Selector : : SimpleSelector : : Type : : PseudoClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    . value  =  Selector : : SimpleSelector : : PseudoClass  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        . type  =  pseudo_class , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        . nth_child_pattern  =  nth_child_pattern . release_value ( )  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! allow_of ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Parse the `of <selector-list>` syntax
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  maybe_of  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! ( maybe_of . is ( Token : : Type : : Ident )  & &  maybe_of . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " of " sv ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  selector_list  =  TRY ( parse_a_selector_list ( tokens ,  SelectorType : : Standalone ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . type  =  Selector : : SimpleSelector : : Type : : PseudoClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . value  =  Selector : : SimpleSelector : : PseudoClass  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    . type  =  pseudo_class , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    . nth_child_pattern  =  nth_child_pattern . release_value ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    . argument_selector_list  =  move ( selector_list )  } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  pseudo_function  =  pseudo_class_token . function ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_function . name ( ) . equals_ignoring_ascii_case ( " is " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            | |  pseudo_function . name ( ) . equals_ignoring_ascii_case ( " where " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 17:45:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  function_token_stream  =  TokenStream ( pseudo_function . values ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // NOTE: Because it's forgiving, even complete garbage will parse OK as an empty selector-list.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  argument_selector_list  =  MUST ( parse_a_selector_list ( function_token_stream ,  SelectorType : : Standalone ,  SelectorParsingMode : : Forgiving ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 17:45:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . type  =  Selector : : SimpleSelector : : Type : : PseudoClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . value  =  Selector : : SimpleSelector : : PseudoClass  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    . type  =  pseudo_function . name ( ) . equals_ignoring_ascii_case ( " is " sv ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 17:45:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        ?  Selector : : SimpleSelector : : PseudoClass : : Type : : Is 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        :  Selector : : SimpleSelector : : PseudoClass : : Type : : Where , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    . argument_selector_list  =  move ( argument_selector_list )  } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 17:45:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_function . name ( ) . equals_ignoring_ascii_case ( " not " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  function_token_stream  =  TokenStream ( pseudo_function . values ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  not_selector  =  TRY ( parse_a_selector_list ( function_token_stream ,  SelectorType : : Standalone ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . type  =  Selector : : SimpleSelector : : Type : : PseudoClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . value  =  Selector : : SimpleSelector : : PseudoClass  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    . type  =  Selector : : SimpleSelector : : PseudoClass : : Type : : Not , 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    . argument_selector_list  =  move ( not_selector )  } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_function . name ( ) . equals_ignoring_ascii_case ( " lang " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( pseudo_function . values ( ) . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " Empty :lang() selector " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: Support multiple, comma-separated, language ranges.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:42:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Vector < FlyString >  languages ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            languages . append ( pseudo_function . values ( ) . first ( ) . token ( ) . to_string ( ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . type  =  Selector : : SimpleSelector : : Type : : PseudoClass , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . value  =  Selector : : SimpleSelector : : PseudoClass  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    . type  =  Selector : : SimpleSelector : : PseudoClass : : Type : : Lang , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    . languages  =  move ( languages )  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_function . name ( ) . equals_ignoring_ascii_case ( " nth-child " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parse_nth_child_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : NthChild ,  pseudo_function . values ( ) ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_function . name ( ) . equals_ignoring_ascii_case ( " nth-last-child " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parse_nth_child_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : NthLastChild ,  pseudo_function . values ( ) ,  true ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_function . name ( ) . equals_ignoring_ascii_case ( " nth-of-type " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parse_nth_child_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : NthOfType ,  pseudo_function . values ( ) ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( pseudo_function . name ( ) . equals_ignoring_ascii_case ( " nth-last-of-type " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parse_nth_child_selector ( Selector : : SimpleSelector : : PseudoClass : : Type : : NthLastOfType ,  pseudo_function . values ( ) ,  false ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 16:21:01 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Unrecognized pseudo-class function: ':{}'() " ,  pseudo_function . name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    dbgln_if ( CSS_PARSER_DEBUG ,  " Unexpected Block in pseudo-class name, expected a function or identifier. '{}' " ,  pseudo_class_token . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Parser : : ParseErrorOr < Optional < Selector : : SimpleSelector > >  Parser : : parse_simple_selector ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  peek_token_ends_selector  =  [ & ] ( )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  value  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ( value . is ( Token : : Type : : EndOfFile )  | |  value . is ( Token : : Type : : Whitespace )  | |  value . is ( Token : : Type : : Comma ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 21:16:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( peek_token_ends_selector ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Optional < Selector : : SimpleSelector >  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:34:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  first_value  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 21:16:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_value . is ( Token : : Type : : Delim ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        u32  delim  =  first_value . token ( ) . delim ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( delim )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' * ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . type  =  Selector : : SimpleSelector : : Type : : Universal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' . ' :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( peek_token_ends_selector ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  class_name_value  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! class_name_value . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " Expected an ident after '.', got: {} " ,  class_name_value . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . type  =  Selector : : SimpleSelector : : Type : : Class , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:42:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                . value  =  Selector : : SimpleSelector : : Name  {  FlyString : : from_utf8 ( class_name_value . token ( ) . ident ( ) ) . release_value_but_fixme_should_propagate_errors ( )  } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' > ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' + ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' ~ ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ' | ' : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Whitespace is not required between the compound-selector and a combinator.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // So, if we see a combinator, return that this compound-selector is done, instead of a syntax error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Optional < Selector : : SimpleSelector >  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " !!! Invalid simple selector! " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 21:16:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_value . is ( Token : : Type : : Hash ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first_value . token ( ) . hash_type ( )  ! =  Token : : HashType : : Id )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Selector contains hash token that is not an id: {} " ,  first_value . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            . type  =  Selector : : SimpleSelector : : Type : : Id , 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:42:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            . value  =  Selector : : SimpleSelector : : Name  {  FlyString : : from_utf8 ( first_value . token ( ) . hash_value ( ) ) . release_value_but_fixme_should_propagate_errors ( )  } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_value . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : SimpleSelector  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            . type  =  Selector : : SimpleSelector : : Type : : TagName , 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-21 17:19:15 +04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: XML requires case-sensitivity for identifiers, while HTML does not. As such, this should be reworked if XML support is added.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-11 19:46:53 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            . value  =  Selector : : SimpleSelector : : Name  {  FlyString : : from_deprecated_fly_string ( first_value . token ( ) . ident ( ) . to_lowercase_string ( ) ) . release_value_but_fixme_should_propagate_errors ( )  } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_value . is_block ( )  & &  first_value . block ( ) . is_square ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_attribute_simple_selector ( first_value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 13:42:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 18:17:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_value . is ( Token : : Type : : Colon ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_pseudo_simple_selector ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-29 21:16:28 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    dbgln_if ( CSS_PARSER_DEBUG ,  " !!! Invalid simple selector! " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Vector < NonnullRefPtr < MediaQuery > >  Parser : : parse_as_media_query_list ( )  
						 
					
						
							
								
									
										
										
										
											2021-09-29 12:56:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  parse_a_media_query_list ( m_token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Vector < NonnullRefPtr < MediaQuery > >  Parser : : parse_a_media_query_list ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-09-29 12:56:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://www.w3.org/TR/mediaqueries-4/#mq-list
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  comma_separated_lists  =  parse_a_comma_separated_list_of_component_values ( tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    AK : : Vector < NonnullRefPtr < MediaQuery > >  media_queries ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 12:56:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  media_query_parts  :  comma_separated_lists )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  stream  =  TokenStream ( media_query_parts ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        media_queries . append ( parse_media_query ( stream ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  media_queries ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								RefPtr < MediaQuery >  Parser : : parse_as_media_query ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://www.w3.org/TR/cssom-1/#parse-a-media-query
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  media_query_list  =  parse_as_media_query_list ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( media_query_list . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  MediaQuery : : create_not_all ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( media_query_list . size ( )  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  media_query_list . first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// `<media-query>`, https://www.w3.org/TR/mediaqueries-4/#typedef-media-query
  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								NonnullRefPtr < MediaQuery >  Parser : : parse_media_query ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-09-29 12:56:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<media-query> = <media-condition>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //                | [ not | only ]? <media-type> [ and <media-condition-without-or> ]?`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `[ not | only ]?`, Returns whether to negate the query
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_initial_modifier  =  [ ] ( auto &  tokens )  - >  Optional < bool >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! token . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  token . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " not " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:50:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " only " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  invalid_media_query  =  [ & ] ( )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // "A media query that does not match the grammar in the previous section must be replaced by `not all`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // during parsing." - https://www.w3.org/TR/mediaqueries-5/#error-handling
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  constexpr  ( CSS_PARSER_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln ( " Invalid media query: " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . dump_all_tokens ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  MediaQuery : : create_not_all ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  media_query  =  MediaQuery : : create ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<media-condition>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  media_condition  =  parse_media_condition ( tokens ,  MediaCondition : : AllowOr : : Yes ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  invalid_media_query ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        media_query - > m_media_condition  =  move ( media_condition ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  media_query ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `[ not | only ]?`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  modifier  =  parse_initial_modifier ( tokens ) ;  modifier . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        media_query - > m_negated  =  modifier . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `<media-type>`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  media_type  =  parse_media_type ( tokens ) ;  media_type . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        media_query - > m_media_type  =  media_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  invalid_media_query ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  media_query ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `[ and <media-condition-without-or> ]?`
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  maybe_and  =  tokens . next_token ( ) ;  maybe_and . is ( Token : : Type : : Ident )  & &  maybe_and . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " and " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  media_condition  =  parse_media_condition ( tokens ,  MediaCondition : : AllowOr : : No ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  invalid_media_query ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            media_query - > m_media_condition  =  move ( media_condition ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  media_query ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  invalid_media_query ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  invalid_media_query ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// `<media-condition>`, https://www.w3.org/TR/mediaqueries-4/#typedef-media-condition
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// `<media-condition-widthout-or>`, https://www.w3.org/TR/mediaqueries-4/#typedef-media-condition-without-or
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// (We distinguish between these two with the `allow_or` parameter.)
  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								OwnPtr < MediaCondition >  Parser : : parse_media_condition ( TokenStream < ComponentValue > &  tokens ,  MediaCondition : : AllowOr  allow_or )  
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<media-not> | <media-in-parens> [ <media-and>* | <media-or>* ]`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `<media-not> = not <media-in-parens>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_media_not  =  [ & ] ( auto &  tokens )  - >  OwnPtr < MediaCondition >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  local_transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  first_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first_token . is ( Token : : Type : : Ident )  & &  first_token . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " not " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  child_condition  =  parse_media_condition ( tokens ,  MediaCondition : : AllowOr : : Yes ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                local_transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  MediaCondition : : from_not ( child_condition . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 12:56:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_media_with_combinator  =  [ & ] ( auto &  tokens ,  StringView  combinator )  - >  OwnPtr < MediaCondition >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  local_transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  first  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first . is ( Token : : Type : : Ident )  & &  first . token ( ) . ident ( ) . equals_ignoring_ascii_case ( combinator ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  media_in_parens  =  parse_media_in_parens ( tokens ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                local_transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  media_in_parens ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<media-and> = and <media-in-parens>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_media_and  =  [ & ] ( auto &  tokens )  {  return  parse_media_with_combinator ( tokens ,  " and " sv ) ;  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `<media-or> = or <media-in-parens>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_media_or  =  [ & ] ( auto &  tokens )  {  return  parse_media_with_combinator ( tokens ,  " or " sv ) ;  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `<media-not>`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  maybe_media_not  =  parse_media_not ( tokens ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  maybe_media_not . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<media-in-parens> [ <media-and>* | <media-or>* ]`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  maybe_media_in_parens  =  parse_media_in_parens ( tokens ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Only `<media-in-parens>`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  maybe_media_in_parens . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 17:16:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        Vector < NonnullOwnPtr < MediaCondition > >  child_conditions ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        child_conditions . append ( maybe_media_in_parens . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // `<media-and>*`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  media_and  =  parse_media_and ( tokens ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            child_conditions . append ( media_and . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  next_media_and  =  parse_media_and ( tokens ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    child_conditions . append ( next_media_and . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // We failed - invalid syntax!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-30 14:25:30 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaCondition : : from_and_list ( move ( child_conditions ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // `<media-or>*`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( allow_or  = =  MediaCondition : : AllowOr : : Yes )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  media_or  =  parse_media_or ( tokens ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                child_conditions . append ( media_or . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( auto  next_media_or  =  parse_media_or ( tokens ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        child_conditions . append ( next_media_or . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    // We failed - invalid syntax!
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  MediaCondition : : from_or_list ( move ( child_conditions ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-24 15:11:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// `<media-feature>`, https://www.w3.org/TR/mediaqueries-4/#typedef-media-feature
  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < MediaFeature >  Parser : : parse_media_feature ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `[ <mf-plain> | <mf-boolean> | <mf-range> ]`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<mf-name> = <ident>`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    struct  MediaFeatureName  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        enum  Type  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            Normal , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            Min , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            Max 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        MediaFeatureID  id ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_mf_name  =  [ ] ( auto &  tokens ,  bool  allow_min_max_prefix )  - >  Optional < MediaFeatureName >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  name  =  token . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  id  =  media_feature_id_from_string ( name ) ;  id . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  MediaFeatureName  {  MediaFeatureName : : Type : : Normal ,  id . value ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( allow_min_max_prefix  & &  ( name . starts_with ( " min- " sv ,  CaseSensitivity : : CaseInsensitive )  | |  name . starts_with ( " max- " sv ,  CaseSensitivity : : CaseInsensitive ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  adjusted_name  =  name . substring_view ( 4 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 17:39:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  id  =  media_feature_id_from_string ( adjusted_name ) ;  id . has_value ( )  & &  media_feature_type_is_range ( id . value ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  MediaFeatureName  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        name . starts_with ( " min- " sv ,  CaseSensitivity : : CaseInsensitive )  ?  MediaFeatureName : : Type : : Min  :  MediaFeatureName : : Type : : Max , 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        id . value ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<mf-boolean> = <mf-name>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_mf_boolean  =  [ & ] ( auto &  tokens )  - >  Optional < MediaFeature >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_name  =  parse_mf_name ( tokens ,  false ) ;  maybe_name . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  MediaFeature : : boolean ( maybe_name - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<mf-plain> = <mf-name> : <mf-value>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_mf_plain  =  [ & ] ( auto &  tokens )  - >  Optional < MediaFeature >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_name  =  parse_mf_name ( tokens ,  true ) ;  maybe_name . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( tokens . next_token ( ) . is ( Token : : Type : : Colon ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  maybe_value  =  parse_media_feature_value ( maybe_name - > id ,  tokens ) ;  maybe_value . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        switch  ( maybe_name - > type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        case  MediaFeatureName : : Type : : Normal : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            return  MediaFeature : : plain ( maybe_name - > id ,  maybe_value . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        case  MediaFeatureName : : Type : : Min : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            return  MediaFeature : : min ( maybe_name - > id ,  maybe_value . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        case  MediaFeatureName : : Type : : Max : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            return  MediaFeature : : max ( maybe_name - > id ,  maybe_value . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<mf-lt> = '<' '='?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  <mf-gt> = '>' '='?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  <mf-eq> = '='
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  <mf-comparison> = <mf-lt> | <mf-gt> | <mf-eq>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_comparison  =  [ ] ( auto &  tokens )  - >  Optional < MediaFeature : : Comparison >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  first  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first . is ( Token : : Type : : Delim ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  first_delim  =  first . token ( ) . delim ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( first_delim  = =  ' = ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  MediaFeature : : Comparison : : Equal ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:34:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( first_delim  = =  ' < ' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  second  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( second . is_delim ( ' = ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  MediaFeature : : Comparison : : LessThanOrEqual ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  MediaFeature : : Comparison : : LessThan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-13 17:34:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( first_delim  = =  ' > ' )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  second  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( second . is_delim ( ' = ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  MediaFeature : : Comparison : : GreaterThanOrEqual ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  MediaFeature : : Comparison : : GreaterThan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  flip  =  [ ] ( MediaFeature : : Comparison  comparison )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( comparison )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  MediaFeature : : Comparison : : Equal : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaFeature : : Comparison : : Equal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  MediaFeature : : Comparison : : LessThan : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaFeature : : Comparison : : GreaterThan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  MediaFeature : : Comparison : : LessThanOrEqual : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaFeature : : Comparison : : GreaterThanOrEqual ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  MediaFeature : : Comparison : : GreaterThan : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaFeature : : Comparison : : LessThan ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  MediaFeature : : Comparison : : GreaterThanOrEqual : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaFeature : : Comparison : : LessThanOrEqual ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  comparisons_match  =  [ ] ( MediaFeature : : Comparison  a ,  MediaFeature : : Comparison  b )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  MediaFeature : : Comparison : : Equal : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  b  = =  MediaFeature : : Comparison : : Equal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  MediaFeature : : Comparison : : LessThan : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  MediaFeature : : Comparison : : LessThanOrEqual : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  b  = =  MediaFeature : : Comparison : : LessThan  | |  b  = =  MediaFeature : : Comparison : : LessThanOrEqual ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  MediaFeature : : Comparison : : GreaterThan : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  MediaFeature : : Comparison : : GreaterThanOrEqual : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  b  = =  MediaFeature : : Comparison : : GreaterThan  | |  b  = =  MediaFeature : : Comparison : : GreaterThanOrEqual ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `<mf-range> = <mf-name> <mf-comparison> <mf-value>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //             | <mf-value> <mf-comparison> <mf-name>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //             | <mf-value> <mf-lt> <mf-name> <mf-lt> <mf-value>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //             | <mf-value> <mf-gt> <mf-name> <mf-gt> <mf-value>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_mf_range  =  [ & ] ( auto &  tokens )  - >  Optional < MediaFeature >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // `<mf-name> <mf-comparison> <mf-value>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: We have to check for <mf-name> first, since all <mf-name>s will also parse as <mf-value>.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 17:39:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_name  =  parse_mf_name ( tokens ,  false ) ;  maybe_name . has_value ( )  & &  media_feature_type_is_range ( maybe_name - > id ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  maybe_comparison  =  parse_comparison ( tokens ) ;  maybe_comparison . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  maybe_value  =  parse_media_feature_value ( maybe_name - > id ,  tokens ) ;  maybe_value . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! tokens . has_next_token ( )  & &  ! maybe_value - > is_ident ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        return  MediaFeature : : half_range ( maybe_value . release_value ( ) ,  flip ( maybe_comparison . release_value ( ) ) ,  maybe_name - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //  `<mf-value> <mf-comparison> <mf-name>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // | <mf-value> <mf-lt> <mf-name> <mf-lt> <mf-value>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // | <mf-value> <mf-gt> <mf-name> <mf-gt> <mf-value>`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: To parse the first value, we need to first find and parse the <mf-name> so we know what value types to parse.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       To allow for <mf-value> to be any number of tokens long, we scan forward until we find a comparison, and then
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       treat the next non-whitespace token as the <mf-name>, which should be correct as long as they don't add a value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       type that can include a comparison in it. :^)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Optional < MediaFeatureName >  maybe_name ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // This transaction is never committed, we just use it to rewind automatically.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  temp_transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            while  ( tokens . has_next_token ( )  & &  ! maybe_name . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  maybe_comparison  =  parse_comparison ( tokens ) ;  maybe_comparison . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    // We found a comparison, so the next non-whitespace token should be the <mf-name>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    maybe_name  =  parse_mf_name ( tokens ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Now, we can parse the range properly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( maybe_name . has_value ( )  & &  media_feature_type_is_range ( maybe_name - > id ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  maybe_left_value  =  parse_media_feature_value ( maybe_name - > id ,  tokens ) ;  maybe_left_value . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  maybe_left_comparison  =  parse_comparison ( tokens ) ;  maybe_left_comparison . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    tokens . next_token ( ) ;  // The <mf-name> which we already parsed above.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        return  MediaFeature : : half_range ( maybe_left_value . release_value ( ) ,  maybe_left_comparison . release_value ( ) ,  maybe_name - > id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( auto  maybe_right_comparison  =  parse_comparison ( tokens ) ;  maybe_right_comparison . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        if  ( auto  maybe_right_value  =  parse_media_feature_value ( maybe_name - > id ,  tokens ) ;  maybe_right_value . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            // For this to be valid, the following must be true:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            // - Comparisons must either both be >/>= or both be </<=.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            // - Neither comparison can be `=`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            // - Neither value can be an ident.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            auto  left_comparison  =  maybe_left_comparison . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            auto  right_comparison  =  maybe_right_comparison . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            if  ( ! tokens . has_next_token ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                                & &  comparisons_match ( left_comparison ,  right_comparison ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                                & &  left_comparison  ! =  MediaFeature : : Comparison : : Equal 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                                & &  ! maybe_left_value - > is_ident ( )  & &  ! maybe_right_value - > is_ident ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                                transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:51:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                                return  MediaFeature : : range ( maybe_left_value . release_value ( ) ,  left_comparison ,  maybe_name - > id ,  right_comparison ,  maybe_right_value . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  maybe_mf_boolean  =  parse_mf_boolean ( tokens ) ;  maybe_mf_boolean . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  maybe_mf_boolean . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  maybe_mf_plain  =  parse_mf_plain ( tokens ) ;  maybe_mf_plain . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  maybe_mf_plain . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 16:24:43 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  maybe_mf_range  =  parse_mf_range ( tokens ) ;  maybe_mf_range . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  maybe_mf_range . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < MediaQuery : : MediaType >  Parser : : parse_media_type ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! token . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 08:58:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-03 08:58:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  ident  =  token . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  media_type_from_string ( ident ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// `<media-in-parens>`, https://www.w3.org/TR/mediaqueries-4/#typedef-media-in-parens
  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								OwnPtr < MediaCondition >  Parser : : parse_media_in_parens ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `<media-in-parens> = ( <media-condition> ) | ( <media-feature> ) | <general-enclosed>`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `( <media-condition> ) | ( <media-feature> )`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  first_token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_token . is_block ( )  & &  first_token . block ( ) . is_paren ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TokenStream  inner_token_stream  {  first_token . block ( ) . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_media_condition  =  parse_media_condition ( inner_token_stream ,  MediaCondition : : AllowOr : : Yes ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  maybe_media_condition . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_media_feature  =  parse_media_feature ( inner_token_stream ) ;  maybe_media_feature . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaCondition : : from_feature ( maybe_media_feature . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `<general-enclosed>`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-16 19:47:58 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: We should only be taking this branch if the grammar doesn't match the above options.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //        Currently we take it if the above fail to parse, which is different.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //        eg, `@media (min-width: 76yaks)` is valid grammar, but does not parse because `yaks` isn't a unit.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  maybe_general_enclosed  =  parse_general_enclosed ( tokens ) ;  maybe_general_enclosed . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  MediaCondition : : from_general_enclosed ( maybe_general_enclosed . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-01 11:44:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 20:54:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 12:56:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 17:52:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// `<mf-value>`, https://www.w3.org/TR/mediaqueries-4/#typedef-mf-value
  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < MediaFeatureValue >  Parser : : parse_media_feature_value ( MediaFeatureID  media_feature ,  TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-12-29 17:52:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Identifiers
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . peek_token ( ) . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  value_id_from_string ( tokens . next_token ( ) . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-10 12:43:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . has_value ( )  & &  media_feature_accepts_identifier ( media_feature ,  ident . value ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-10 12:43:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaFeatureValue ( ident . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // One branch for each member of the MediaFeatureValueType enum:
 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 17:52:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Boolean (<mq-boolean> in the spec: a 1 or 0)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( media_feature_accepts_type ( media_feature ,  MediaFeatureValueType : : Boolean ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  first  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 21:01:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first . is ( Token : : Type : : Number )  & &  first . token ( ) . number ( ) . is_integer ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            & &  ( first . token ( ) . number_value ( )  = =  0  | |  first . token ( ) . number_value ( )  = =  1 ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaFeatureValue ( first . token ( ) . number_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 14:09:19 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 17:52:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Integer
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( media_feature_accepts_type ( media_feature ,  MediaFeatureValueType : : Integer ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  first  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first . is ( Token : : Type : : Number )  & &  first . token ( ) . number ( ) . is_integer ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaFeatureValue ( first . token ( ) . number_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 17:57:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 17:52:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Length
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( media_feature_accepts_type ( media_feature ,  MediaFeatureValueType : : Length ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  first  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  length  =  parse_length ( first ) ;  length . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaFeatureValue ( length . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Ratio
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( media_feature_accepts_type ( media_feature ,  MediaFeatureValueType : : Ratio ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  ratio  =  parse_ratio ( tokens ) ;  ratio . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaFeatureValue ( ratio . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Resolution
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( media_feature_accepts_type ( media_feature ,  MediaFeatureValueType : : Resolution ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  first  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 15:29:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  resolution  =  parse_dimension ( first ) ;  resolution . has_value ( )  & &  resolution - > is_resolution ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  MediaFeatureValue ( resolution - > resolution ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-08 16:37:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 17:52:14 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								RefPtr < Supports >  Parser : : parse_as_supports ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  parse_a_supports ( m_token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								RefPtr < Supports >  Parser : : parse_a_supports ( TokenStream < T > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  component_values  =  parse_a_list_of_component_values ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream < ComponentValue >  token_stream  {  component_values  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_condition  =  parse_supports_condition ( token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    token_stream . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( maybe_condition  & &  ! token_stream . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Supports : : create ( maybe_condition . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								OwnPtr < Supports : : Condition >  Parser : : parse_supports_condition ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  peeked_token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `not <supports-in-parens>`
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( peeked_token . is ( Token : : Type : : Ident )  & &  peeked_token . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " not " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  child  =  parse_supports_in_parens ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! child . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  condition  =  make < Supports : : Condition > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        condition - > type  =  Supports : : Condition : : Type : : Not ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        condition - > children . append ( child . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  condition ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `  <supports-in-parens> [ and <supports-in-parens> ]*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  | <supports-in-parens> [ or <supports-in-parens> ]*`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Supports : : InParens >  children ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < Supports : : Condition : : Type >  condition_type  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  as_condition_type  =  [ ] ( auto &  token )  - >  Optional < Supports : : Condition : : Type >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! token . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  token . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " and " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Supports : : Condition : : Type : : And ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " or " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Supports : : Condition : : Type : : Or ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! children . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Expect `and` or `or` here
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_combination  =  as_condition_type ( tokens . next_token ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_combination . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! condition_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                condition_type  =  maybe_combination . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( maybe_combination  ! =  condition_type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  in_parens  =  parse_supports_in_parens ( tokens ) ;  in_parens . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            children . append ( in_parens . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( children . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  condition  =  make < Supports : : Condition > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    condition - > type  =  condition_type . value_or ( Supports : : Condition : : Type : : Or ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    condition - > children  =  move ( children ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  condition ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Supports : : InParens >  Parser : : parse_supports_in_parens ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `( <supports-condition> )`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  first_token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_token . is_block ( )  & &  first_token . block ( ) . is_paren ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TokenStream  child_tokens  {  first_token . block ( ) . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  condition  =  parse_supports_condition ( child_tokens ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( child_tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Supports : : InParens  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                . value  =  {  condition . release_nonnull ( )  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `<supports-feature>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  feature  =  parse_supports_feature ( tokens ) ;  feature . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Supports : : InParens  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            . value  =  {  feature . release_value ( )  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `<general-enclosed>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  general_enclosed  =  parse_general_enclosed ( tokens ) ;  general_enclosed . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Supports : : InParens  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-24 14:20:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            . value  =  general_enclosed . release_value ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Supports : : Feature >  Parser : : parse_supports_feature ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  first_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<supports-decl>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_token . is_block ( )  & &  first_token . block ( ) . is_paren ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TokenStream  block_tokens  {  first_token . block ( ) . values ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 17:22:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Parsing and then converting back to a string is weird.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  declaration  =  consume_a_declaration ( block_tokens ) ;  declaration . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Supports : : Feature  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-28 16:54:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                Supports : : Declaration  {  declaration - > to_string ( ) . release_value_but_fixme_should_propagate_errors ( ) ,  JS : : make_handle ( m_context . realm ( ) )  } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 17:22:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<supports-selector-fn>`
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_token . is_function ( )  & &  first_token . function ( ) . name ( ) . equals_ignoring_ascii_case ( " selector " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 17:22:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Parsing and then converting back to a string is weird.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        StringBuilder  builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  item  :  first_token . function ( ) . values ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 19:04:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            builder . append ( item . to_string ( ) . release_value_but_fixme_should_propagate_errors ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 17:22:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Supports : : Feature  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-28 16:54:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Supports : : Selector  {  builder . to_string ( ) . release_value_but_fixme_should_propagate_errors ( ) ,  JS : : make_handle ( m_context . realm ( ) )  } 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-19 17:22:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-22 17:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/mediaqueries-4/#typedef-general-enclosed
  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < GeneralEnclosed >  Parser : : parse_general_enclosed ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-22 17:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  first_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-22 17:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 12:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `[ <function-token> <any-value>? ) ]`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_token . is_function ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-17 12:13:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  GeneralEnclosed  {  first_token . to_string ( ) . release_value_but_fixme_should_propagate_errors ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-22 17:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-29 12:27:42 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `( <any-value>? )`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_token . is_block ( )  & &  first_token . block ( ) . is_paren ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-17 12:13:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  GeneralEnclosed  {  first_token . to_string ( ) . release_value_but_fixme_should_propagate_errors ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 16:33:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-22 17:27:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.4.1. Consume a list of rules
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#consume-list-of-rules
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Vector < NonnullRefPtr < Rule > >  Parser : : consume_a_list_of_rules ( TokenStream < T > &  tokens ,  TopLevel  top_level )  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To consume a list of rules, given a top-level flag:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Create an initially empty list of rules.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < NonnullRefPtr < Rule > >  rules ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Repeatedly consume the next input token:
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <whitespace-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Whitespace ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Do nothing.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <EOF-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : EndOfFile ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Return the list of rules.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  rules ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <CDO-token>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <CDC-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : CDO )  | |  token . is ( Token : : Type : : CDC ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // If the top-level flag is set, do nothing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( top_level  = =  TopLevel : : Yes ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Otherwise, reconsume the current input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Consume a qualified rule. If anything is returned, append it to the list of rules.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  maybe_qualified  =  consume_a_qualified_rule ( tokens ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-01 16:49:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                rules . append ( maybe_qualified . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <at-keyword-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : AtKeyword ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Reconsume the current input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Consume an at-rule, and append the returned value to the list of rules.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            rules . append ( consume_an_at_rule ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:03:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // anything else
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Reconsume the current input token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Consume a qualified rule. If anything is returned, append it to the list of rules.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  maybe_qualified  =  consume_a_qualified_rule ( tokens ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                rules . append ( maybe_qualified . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.4.2. Consume an at-rule
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#consume-at-rule
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								NonnullRefPtr < Rule >  Parser : : consume_an_at_rule ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To consume an at-rule:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Consume the next input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  name_ident  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 17:51:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY ( name_ident . is ( Token : : Type : : AtKeyword ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Create a new at-rule with its name set to the value of the current input token, its prelude initially set to an empty list, and its value initially set to nothing.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: We create the Rule fully initialized when we return it instead.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-15 11:28:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  at_rule_name  =  FlyString : : from_utf8 ( ( ( Token ) name_ident ) . at_keyword ( ) ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 17:03:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  prelude ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < Block >  block ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Repeatedly consume the next input token:
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <semicolon-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Semicolon ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Return the at-rule.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Rule : : make_at_rule ( move ( at_rule_name ) ,  move ( prelude ) ,  move ( block ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <EOF-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : EndOfFile ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // This is a parse error. Return the at-rule.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-24 20:20:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            log_parse_error ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Rule : : make_at_rule ( move ( at_rule_name ) ,  move ( prelude ) ,  move ( block ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <{-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : OpenCurly ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								            // Consume a simple block and assign it to the at-rule’  
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 17:03:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            block  =  consume_a_simple_block ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Rule : : make_at_rule ( move ( at_rule_name ) ,  move ( prelude ) ,  move ( block ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // simple block with an associated token of <{-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  constexpr  ( IsSame < T ,  ComponentValue > )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ComponentValue  const &  component_value  =  token ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 16:32:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( component_value . is_block ( )  & &  component_value . block ( ) . is_curly ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								                // Assign the block to the at-rule’  
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 17:03:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                block  =  component_value . block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  Rule : : make_at_rule ( move ( at_rule_name ) ,  move ( prelude ) ,  move ( block ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 16:32:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // anything else
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Reconsume the current input token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								            // Consume a component value. Append the returned value to the at-rule’  
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 17:03:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            prelude . append ( consume_a_component_value ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:46:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:50:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.4.3. Consume a qualified rule
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#consume-qualified-rule
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								RefPtr < Rule >  Parser : : consume_a_qualified_rule ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:50:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To consume a qualified rule:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Create a new qualified rule with its prelude initially set to an empty list, and its value initially set to nothing.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: We create the Rule fully initialized when we return it instead.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 17:03:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  prelude ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < Block >  block ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:50:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Repeatedly consume the next input token:
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:50:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <EOF-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : EndOfFile ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:50:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // This is a parse error. Return nothing.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-24 20:20:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            log_parse_error ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:50:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <{-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : OpenCurly ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:50:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								            // Consume a simple block and assign it to the qualified rule’  
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 17:03:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            block  =  consume_a_simple_block ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Rule : : make_qualified_rule ( move ( prelude ) ,  move ( block ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:50:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // simple block with an associated token of <{-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  constexpr  ( IsSame < T ,  ComponentValue > )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ComponentValue  const &  component_value  =  token ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 15:43:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( component_value . is_block ( )  & &  component_value . block ( ) . is_curly ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:50:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								                // Assign the block to the qualified rule’  
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 17:03:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                block  =  component_value . block ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  Rule : : make_qualified_rule ( move ( prelude ) ,  move ( block ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 15:43:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:50:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // anything else
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Reconsume the current input token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								            // Consume a component value. Append the returned value to the qualified rule’  
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 17:03:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            prelude . append ( consume_a_component_value ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 13:50:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 16:44:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								// 5.4.4. Consume a style block’   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#consume-a-style-blocks-contents
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Vector < DeclarationOrAtRule >  Parser : : consume_a_style_blocks_contents ( TokenStream < T > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // To consume a style block’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Create an initially empty list of declarations decls, and an initially empty list of rules rules.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < DeclarationOrAtRule >  declarations ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < DeclarationOrAtRule >  rules ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Repeatedly consume the next input token:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <whitespace-token>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <semicolon-token>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Whitespace )  | |  token . is ( Token : : Type : : Semicolon ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Do nothing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <EOF-token>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : EndOfFile ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Extend decls with rules, then return decls.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            declarations . extend ( move ( rules ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  declarations ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <at-keyword-token>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : AtKeyword ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Reconsume the current input token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Consume an at-rule, and append the result to rules.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            rules . empend ( consume_an_at_rule ( tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <ident-token>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Initialize a temporary list initially filled with the current input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Vector < ComponentValue >  temporary_list ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 16:44:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            temporary_list . append ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // As long as the next input token is anything other than a <semicolon-token> or <EOF-token>,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // consume a component value and append it to the temporary list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  next_input_token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( next_input_token . is ( Token : : Type : : Semicolon )  | |  next_input_token . is ( Token : : Type : : EndOfFile ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                temporary_list . append ( consume_a_component_value ( tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Consume a declaration from the temporary list. If anything was returned, append it to decls.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  token_stream  =  TokenStream ( temporary_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  maybe_declaration  =  consume_a_declaration ( token_stream ) ;  maybe_declaration . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                declarations . empend ( maybe_declaration . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <delim-token> with a value of "&" (U+0026 AMPERSAND)
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is_delim ( ' & ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 16:44:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Reconsume the current input token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Consume a qualified rule. If anything was returned, append it to rules.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  qualified_rule  =  consume_a_qualified_rule ( tokens ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                rules . empend ( qualified_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // anything else
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // This is a parse error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            log_parse_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Reconsume the current input token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // As long as the next input token is anything other than a <semicolon-token> or <EOF-token>,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // consume a component value and throw away the returned value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  peek  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( peek . is ( Token : : Type : : Semicolon )  | |  peek . is ( Token : : Type : : EndOfFile ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                ( void ) consume_a_component_value ( tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < >  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ComponentValue  Parser : : consume_a_component_value ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:14:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This overload is called once tokens have already been converted into component values,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //       so we do not need to do the work in the more general overload.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:14:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.4.7. Consume a component value
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#consume-component-value
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ComponentValue  Parser : : consume_a_component_value ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:14:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To consume a component value:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Consume the next input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:14:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // If the current input token is a <{-token>, <[-token>, or <(-token>, consume a simple block and return it.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( token . is ( Token : : Type : : OpenCurly )  | |  token . is ( Token : : Type : : OpenSquare )  | |  token . is ( Token : : Type : : OpenParen ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ComponentValue ( consume_a_simple_block ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:14:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Otherwise, if the current input token is a <function-token>, consume a function and return it.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( token . is ( Token : : Type : : Function ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ComponentValue ( consume_a_function ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:14:31 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Otherwise, return the current input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  ComponentValue ( token ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.4.8. Consume a simple block
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#consume-simple-block
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-04-12 14:08:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								NonnullRefPtr < Block >  Parser : : consume_a_simple_block ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This algorithm assumes that the current input token has already been checked
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // to be an <{-token>, <[-token>, or <(-token>.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To consume a simple block:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The ending token is the mirror variant of the current input token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // (E.g. if it was called with <[-token>, the ending token is <]-token>.)
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  ending_token  =  ( ( Token ) tokens . current_token ( ) ) . mirror_variant ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Create a simple block with its associated token set to the current input token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // and with its value initially set to an empty list.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:05:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: We create the Block fully initialized when we return it instead.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Token  block_token  =  tokens . current_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  block_values ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Repeatedly consume the next input token and process it as follows:
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // ending token
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( ending_token ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Return the block.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:05:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Block : : create ( move ( block_token ) ,  move ( block_values ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <EOF-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : EndOfFile ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // This is a parse error. Return the block.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-24 20:20:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            log_parse_error ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:05:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Block : : create ( move ( block_token ) ,  move ( block_values ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // anything else
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Reconsume the current input token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Consume a component value and append it to the value of the block.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:05:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            block_values . empend ( consume_a_component_value ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.4.9. Consume a function
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#consume-function
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-04-12 13:35:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								NonnullRefPtr < Function >  Parser : : consume_a_function ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This algorithm assumes that the current input token has already been checked to be a <function-token>.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  name_ident  =  tokens . current_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY ( name_ident . is ( Token : : Type : : Function ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To consume a function:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Create a function with its name equal to the value of the current input token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // and with its value initially set to an empty list.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:44:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: We create the Function fully initialized when we return it instead.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 18:55:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  function_name  =  FlyString : : from_utf8 ( ( ( Token ) name_ident ) . function ( ) ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:44:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  function_values ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Repeatedly consume the next input token and process it as follows:
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <)-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : CloseParen ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Return the function.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:44:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Function : : create ( move ( function_name ) ,  move ( function_values ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <EOF-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : EndOfFile ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // This is a parse error. Return the function.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-24 20:20:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            log_parse_error ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:44:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Function : : create ( move ( function_name ) ,  move ( function_values ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // anything else
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Reconsume the current input token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								            // Consume a component value and append the returned value to the function’  
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:44:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            function_values . append ( consume_a_component_value ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:40:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:21:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.4.6. Consume a declaration
  
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#consume-declaration
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-03-31 14:36:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Declaration >  Parser : : consume_a_declaration ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This algorithm assumes that the next input token has already been checked to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // be an <ident-token>.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: This is not true in our implementation! For convenience, we both skip whitespace
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //       and gracefully handle the first token not being an <ident-token>.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // To consume a declaration:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Consume the next input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: Not to spec, handle the case where the input token *isn't* an <ident-token>.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! token . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 15:54:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Create a new declaration with its name set to the value of the current input token
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // and its value initially set to the empty list.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:16:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: We create a fully-initialized Declaration just before returning it instead.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-15 11:28:23 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  declaration_name  =  FlyString : : from_utf8 ( ( ( Token ) token ) . ident ( ) ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:16:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  declaration_values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Important  declaration_important  =  Important : : No ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. While the next input token is a <whitespace-token>, consume the next input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. If the next input token is anything other than a <colon-token>, this is a parse error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Return nothing.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  maybe_colon  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_colon . is ( Token : : Type : : Colon ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-04-24 20:20:14 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        log_parse_error ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Otherwise, consume the next input token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. While the next input token is a <whitespace-token>, consume the next input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. As long as the next input token is anything other than an <EOF-token>, consume a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    //    component value and append it to the declaration’  
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( tokens . peek_token ( ) . is ( Token : : Type : : EndOfFile ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:16:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        declaration_values . append ( consume_a_component_value ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								    // 5. If the last two non-<whitespace-token>s in the declaration’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    with the value "!" followed by an <ident-token> with a value that is an ASCII case-insensitive
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    //    match for "important", remove them from the declaration’ ’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    important flag to true.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:16:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( declaration_values . size ( )  > =  2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Walk backwards from the end until we find "important"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Optional < size_t >  important_index ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:16:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( size_t  i  =  declaration_values . size ( )  -  1 ;  i  >  0 ;  i - - )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  value  =  declaration_values [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-17 15:21:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( value . is ( Token : : Type : : Ident )  & &  Infra : : is_ascii_case_insensitive_match ( value . token ( ) . ident ( ) ,  " important " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                important_index  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( value . is ( Token : : Type : : Whitespace ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Walk backwards from important until we find "!"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( important_index . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            Optional < size_t >  bang_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( size_t  i  =  important_index . value ( )  -  1 ;  i  >  0 ;  i - - )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:16:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  value  =  declaration_values [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( value . is_delim ( ' ! ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    bang_index  =  i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( value . is ( Token : : Type : : Whitespace ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( bang_index . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:16:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                declaration_values . remove ( important_index . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                declaration_values . remove ( bang_index . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                declaration_important  =  Important : : Yes ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								    // 6. While the last token in the declaration’  
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:16:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( ! declaration_values . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_whitespace  =  declaration_values . last ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! ( maybe_whitespace . is ( Token : : Type : : Whitespace ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:16:55 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        declaration_values . take_last ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-28 14:09:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 7. Return the declaration.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  Declaration  {  move ( declaration_name ) ,  move ( declaration_values ) ,  declaration_important  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.4.5. Consume a list of declarations
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#consume-list-of-declarations
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Vector < DeclarationOrAtRule >  Parser : : consume_a_list_of_declarations ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To consume a list of declarations:
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Create an initially empty list of declarations.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < DeclarationOrAtRule >  list_of_declarations ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Repeatedly consume the next input token:
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <whitespace-token>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <semicolon-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Whitespace )  | |  token . is ( Token : : Type : : Semicolon ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Do nothing.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <EOF-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : EndOfFile ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Return the list of declarations.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  list_of_declarations ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <at-keyword-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : AtKeyword ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Reconsume the current input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Consume an at-rule. Append the returned rule to the list of declarations.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:22:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            list_of_declarations . empend ( consume_an_at_rule ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <ident-token>
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Initialize a temporary list initially filled with the current input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Vector < ComponentValue >  temporary_list ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            temporary_list . append ( token ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // As long as the next input token is anything other than a <semicolon-token> or <EOF-token>,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // consume a component value and append it to the temporary list.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  peek  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( peek . is ( Token : : Type : : Semicolon )  | |  peek . is ( Token : : Type : : EndOfFile ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                temporary_list . append ( consume_a_component_value ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Consume a declaration from the temporary list. If anything was returned, append it to the list of declarations.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  token_stream  =  TokenStream ( temporary_list ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  maybe_declaration  =  consume_a_declaration ( token_stream ) ;  maybe_declaration . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:22:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                list_of_declarations . empend ( maybe_declaration . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // anything else
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // This is a parse error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            log_parse_error ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 14:08:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Reconsume the current input token.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // As long as the next input token is anything other than a <semicolon-token> or <EOF-token>,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // consume a component value and throw away the returned value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( ; ; )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  peek  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( peek . is ( Token : : Type : : Semicolon )  | |  peek . is ( Token : : Type : : EndOfFile ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " Discarding token: '{}' " ,  peek . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                ( void ) consume_a_component_value ( tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 15:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								CSSRule *  Parser : : parse_as_css_rule ( )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_rule  =  parse_a_rule ( m_token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( maybe_rule ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  convert_to_rule ( maybe_rule . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.3.5. Parse a rule
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#parse-rule
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								RefPtr < Rule >  Parser : : parse_a_rule ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To parse a rule from input:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 19:05:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < Rule >  rule ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Normalize input, and set input to the result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This is done when initializing the Parser.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. While the next input token from input is a <whitespace-token>, consume the next input token from input.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. If the next input token from input is an <EOF-token>, return a syntax error.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( token . is ( Token : : Type : : EndOfFile ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Otherwise, if the next input token from input is an <at-keyword-token>, consume an at-rule from input, and let rule be the return value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    else  if  ( token . is ( Token : : Type : : AtKeyword ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        rule  =  consume_an_at_rule ( m_token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Otherwise, consume a qualified rule from input and let rule be the return value. If nothing was returned, return a syntax error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  qualified_rule  =  consume_a_qualified_rule ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 16:34:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! qualified_rule ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        rule  =  qualified_rule ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. While the next input token from input is a <whitespace-token>, consume the next input token from input.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. If the next input token from input is an <EOF-token>, return rule. Otherwise, return a syntax error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . peek_token ( ) . is ( Token : : Type : : EndOfFile ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  rule ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 17:01:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.3.4. Parse a list of rules
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#parse-list-of-rules
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2023-03-06 14:17:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Vector < NonnullRefPtr < Rule > >  Parser : : parse_a_list_of_rules ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-29 17:01:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To parse a list of rules from input:
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 16:34:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 17:01:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Normalize input, and set input to the result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This is done when initializing the Parser.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 16:34:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 17:01:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Consume a list of rules from the input, with the top-level flag unset.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  list_of_rules  =  consume_a_list_of_rules ( tokens ,  TopLevel : : No ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Return the returned list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  list_of_rules ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:05:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < StyleProperty >  Parser : : parse_as_supports_condition ( )  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:05:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_declaration  =  parse_a_declaration ( m_token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( maybe_declaration . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  convert_to_style_property ( maybe_declaration . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:05:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.3.6. Parse a declaration
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#parse-a-declaration
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-03-31 14:36:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Declaration >  Parser : : parse_a_declaration ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:05:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To parse a declaration from input:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Normalize input, and set input to the result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This is done when initializing the Parser.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. While the next input token from input is a <whitespace-token>, consume the next input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:05:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. If the next input token from input is not an <ident-token>, return a syntax error.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 21:47:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:06:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:05:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Consume a declaration from input. If anything was returned, return it. Otherwise, return a syntax error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  declaration  =  consume_a_declaration ( tokens ) ;  declaration . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  declaration . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 16:34:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 16:44:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								// 5.3.7. Parse a style block’   
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#parse-style-blocks-contents
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Vector < DeclarationOrAtRule >  Parser : : parse_a_style_blocks_contents ( TokenStream < T > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // To parse a style block’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Normalize input, and set input to the result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This is done when initializing the Parser.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 2. Consume a style block’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  consume_a_style_blocks_contents ( tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.3.8. Parse a list of declarations
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#parse-list-of-declarations
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Vector < DeclarationOrAtRule >  Parser : : parse_a_list_of_declarations ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To parse a list of declarations from input:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:23:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Normalize input, and set input to the result.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:23:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This is done when initializing the Parser.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Consume a list of declarations from input, and return the result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  consume_a_list_of_declarations ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:32:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.3.9. Parse a component value
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#parse-component-value
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < ComponentValue >  Parser : : parse_a_component_value ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:32:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To parse a component value from input:
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:32:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Normalize input, and set input to the result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This is done when initializing the Parser.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:32:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. While the next input token from input is a <whitespace-token>, consume the next input token from input.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. If the next input token from input is an <EOF-token>, return a syntax error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . peek_token ( ) . is ( Token : : Type : : EndOfFile ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:32:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Consume a component value from input and let value be the return value.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  value  =  consume_a_component_value ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:32:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. While the next input token from input is a <whitespace-token>, consume the next input token.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:32:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 6. If the next input token from input is an <EOF-token>, return value. Otherwise, return a syntax error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . peek_token ( ) . is ( Token : : Type : : EndOfFile ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:39:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.3.10. Parse a list of component values
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#parse-list-of-component-values
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Vector < ComponentValue >  Parser : : parse_a_list_of_component_values ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:39:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To parse a list of component values from input:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Normalize input, and set input to the result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This is done when initializing the Parser.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Repeatedly consume a component value from input until an <EOF-token> is returned, appending the returned values (except the final <EOF-token>) into a list. Return the list.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  component_values ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( tokens . peek_token ( ) . is ( Token : : Type : : EndOfFile ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:39:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        component_values . append ( consume_a_component_value ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:39:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  component_values ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:56:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// 5.3.11. Parse a comma-separated list of component values
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#parse-comma-separated-list-of-component-values
  
						 
					
						
							
								
									
										
										
										
											2021-07-03 15:40:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  T >  
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Vector < Vector < ComponentValue > >  Parser : : parse_a_comma_separated_list_of_component_values ( TokenStream < T > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:56:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // To parse a comma-separated list of component values from input:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Normalize input, and set input to the result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: This is done when initializing the Parser.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Let list of cvls be an initially empty list of component value lists.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Vector < ComponentValue > >  list_of_component_value_lists ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:56:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Repeatedly consume a component value from input until an <EOF-token> or <comma-token> is returned,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    appending the returned values (except the final <EOF-token> or <comma-token>) into a list.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    Append the list to list of cvls.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    If it was a <comma-token> that was returned, repeat this step.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  current_list ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( ; ; )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:56:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  component_value  =  consume_a_component_value ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:56:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( component_value . is ( Token : : Type : : EndOfFile ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            list_of_component_value_lists . append ( move ( current_list ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:52:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:56:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( component_value . is ( Token : : Type : : Comma ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            list_of_component_value_lists . append ( move ( current_list ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            current_list  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-02 19:52:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:56:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        current_list . append ( component_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:56:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Return list of cvls.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  list_of_component_value_lists ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-09 16:34:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-15 09:32:02 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template  Vector < Vector < ComponentValue > >  Parser : : parse_a_comma_separated_list_of_component_values ( TokenStream < ComponentValue > & ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 16:21:26 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ElementInlineCSSStyleDeclaration *  Parser : : parse_as_style_attribute ( DOM : : Element &  element )  
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  declarations_and_at_rules  =  parse_a_list_of_declarations ( m_token_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:01:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  [ properties ,  custom_properties ]  =  extract_properties ( declarations_and_at_rules ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 23:22:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  ElementInlineCSSStyleDeclaration : : create ( element ,  move ( properties ) ,  move ( custom_properties ) ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < AK : : URL >  Parser : : parse_url_function ( ComponentValue  const &  component_value ,  AllowedDataUrlType  allowed_data_url_type )  
						 
					
						
							
								
									
										
										
										
											2021-07-22 17:51:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Handle list of media queries. https://www.w3.org/TR/css-cascade-3/#conditional-import
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 17:02:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Handle data: urls (RFC2397)
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 17:51:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-29 08:38:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  convert_string_to_url  =  [ & ] ( StringView &  url_string )  - >  Optional < AK : : URL >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( url_string . starts_with ( " data: " sv ,  CaseSensitivity : : CaseInsensitive ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-29 08:38:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  data_url  =  AK : : URL ( url_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            switch  ( allowed_data_url_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  AllowedDataUrlType : : Image : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( data_url . data_mime_type ( ) . starts_with ( " image " sv ,  CaseSensitivity : : CaseInsensitive ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  data_url ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-14 21:14:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  AllowedDataUrlType : : Font : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( data_url . data_mime_type ( ) . starts_with ( " font " sv ,  CaseSensitivity : : CaseInsensitive ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-06 10:50:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  data_url ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( data_url . data_mime_type ( ) . starts_with ( " application/font " sv ,  CaseSensitivity : : CaseInsensitive ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-14 21:14:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  data_url ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-29 08:38:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 17:41:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  m_context . complete_url ( url_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 17:02:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is ( Token : : Type : : Url ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  url_string  =  component_value . token ( ) . url ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-29 08:38:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  convert_string_to_url ( url_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 17:02:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is_function ( )  & &  component_value . function ( ) . name ( ) . equals_ignoring_ascii_case ( " url " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  function_values  =  component_value . function ( ) . values ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 17:51:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Handle url-modifiers. https://www.w3.org/TR/css-values-4/#url-modifiers
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  function_values . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  value  =  function_values [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 17:51:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( value . is ( Token : : Type : : Whitespace ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( value . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 17:02:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  url_string  =  value . token ( ) . string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-29 08:38:50 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  convert_string_to_url ( url_string ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 17:51:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 17:02:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 17:51:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_url_value ( ComponentValue  const &  component_value ,  AllowedDataUrlType  allowed_data_url_type )  
						 
					
						
							
								
									
										
										
										
											2023-04-21 18:31:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  url  =  parse_url_function ( component_value ,  allowed_data_url_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! url . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  URLStyleValue : : create ( * url ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-21 18:31:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  TElement >  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  Optional < Vector < TElement > >  parse_color_stop_list ( auto &  tokens ,  auto  is_position ,  auto  get_position ,  auto  parse_color ,  auto  parse_dimension )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    enum  class  ElementType  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Garbage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ColorStop , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ColorHint 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_color_stop_list_element  =  [ & ] ( TElement &  element )  - >  ElementType  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  ElementType : : Garbage ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Gfx : : Color  color ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Optional < typename  TElement : : PositionType >  position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Optional < typename  TElement : : PositionType >  second_position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  dimension  =  parse_dimension ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( dimension . has_value ( )  & &  is_position ( * dimension ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // [<T-percentage> <color>] or [<T-percentage>]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            position  =  get_position ( * dimension ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // <T-percentage>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( )  | |  tokens . peek_token ( ) . is ( Token : : Type : : Comma ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                element . transition_hint  =  typename  TElement : : ColorHint  {  * position  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  ElementType : : ColorHint ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // <T-percentage> <color>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_color  =  parse_color ( tokens . next_token ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_color . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  ElementType : : Garbage ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            color  =  * maybe_color ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // [<color> <T-percentage>?]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_color  =  parse_color ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_color . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  ElementType : : Garbage ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            color  =  * maybe_color ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Allow up to [<color> <T-percentage> <T-percentage>] (double-position color stops)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Note: Double-position color stops only appear to be valid in this order.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto  stop_position  :  Array  {  & position ,  & second_position  } )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( tokens . has_next_token ( )  & &  ! tokens . peek_token ( ) . is ( Token : : Type : : Comma ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  dimension  =  parse_dimension ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! dimension . has_value ( )  | |  ! is_position ( * dimension ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  ElementType : : Garbage ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    * stop_position  =  get_position ( * dimension ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        element . color_stop  =  typename  TElement : : ColorStop  {  color ,  position ,  second_position  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ElementType : : ColorStop ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TElement  first_element  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parse_color_stop_list_element ( first_element )  ! =  ElementType : : ColorStop ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < TElement >  color_stops  {  first_element  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TElement  list_element  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! tokens . next_token ( ) . is ( Token : : Type : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  element_type  =  parse_color_stop_list_element ( list_element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( element_type  = =  ElementType : : ColorHint )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // <color-hint>, <color-stop>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . next_token ( ) . is ( Token : : Type : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Note: This fills in the color stop on the same list_element as the color hint (it does not overwrite it).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( parse_color_stop_list_element ( list_element )  ! =  ElementType : : ColorStop ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( element_type  = =  ElementType : : ColorStop )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // <color-stop>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        color_stops . append ( list_element ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  color_stops ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 21:33:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Vector < LinearColorStopListElement > >  Parser : : parse_linear_color_stop_list ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <color-stop-list> =
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   <linear-color-stop> , [ <linear-color-hint>? , <linear-color-stop> ]#
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  parse_color_stop_list < LinearColorStopListElement > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ ] ( Dimension &  dimension )  {  return  dimension . is_length_percentage ( ) ;  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ ] ( Dimension &  dimension )  {  return  dimension . length_percentage ( ) ;  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ & ] ( auto &  token )  {  return  parse_color ( token ) ;  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ & ] ( auto &  token )  {  return  parse_dimension ( token ) ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Vector < AngularColorStopListElement > >  Parser : : parse_angular_color_stop_list ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <angular-color-stop-list> =
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   <angular-color-stop> , [ <angular-color-hint>? , <angular-color-stop> ]#
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  parse_color_stop_list < AngularColorStopListElement > ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ ] ( Dimension &  dimension )  {  return  dimension . is_angle_percentage ( ) ;  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ ] ( Dimension &  dimension )  {  return  dimension . angle_percentage ( ) ;  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ & ] ( auto &  token )  {  return  parse_color ( token ) ;  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        [ & ] ( auto &  token )  {  return  parse_dimension ( token ) ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-06 14:51:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  StringView  consume_if_starts_with ( StringView  str ,  StringView  start ,  auto  found_callback )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( str . starts_with ( start ,  CaseSensitivity : : CaseInsensitive ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        found_callback ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  str . substring_view ( start . length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  str ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-07 22:48:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-11-06 14:51:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_linear_gradient_function ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    using  GradientType  =  LinearGradientStyleValue : : GradientType ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! component_value . is_function ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-06 14:51:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GradientRepeating  repeating_gradient  =  GradientRepeating : : No ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GradientType  gradient_type  {  GradientType : : Standard  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 17:09:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  function_name  =  component_value . function ( ) . name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    function_name  =  consume_if_starts_with ( function_name ,  " -webkit- " sv ,  [ & ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        gradient_type  =  GradientType : : WebKit ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 17:09:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    function_name  =  consume_if_starts_with ( function_name ,  " repeating- " sv ,  [ & ]  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-06 14:51:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        repeating_gradient  =  GradientRepeating : : Yes ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-16 17:09:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! function_name . equals_ignoring_ascii_case ( " linear-gradient " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // linear-gradient() = linear-gradient([ <angle> | to <side-or-corner> ]?, <color-stop-list>)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  tokens  {  component_value . function ( ) . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  has_direction_param  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    LinearGradientStyleValue : : GradientDirection  gradient_direction  =  gradient_type  = =  GradientType : : Standard 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ?  SideOrCorner : : Bottom 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        :  SideOrCorner : : Top ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  to_side  =  [ ] ( StringView  value )  - >  Optional < SideOrCorner >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value . equals_ignoring_ascii_case ( " top " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  SideOrCorner : : Top ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value . equals_ignoring_ascii_case ( " bottom " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  SideOrCorner : : Bottom ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value . equals_ignoring_ascii_case ( " left " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  SideOrCorner : : Left ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value . equals_ignoring_ascii_case ( " right " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  SideOrCorner : : Right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_to_side_or_corner  =  [ & ] ( auto  const &  token )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! token . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( gradient_type  = =  GradientType : : WebKit ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  to_side ( token . token ( ) . ident ( ) ) . has_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  token . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " to " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  first_param  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_param . is ( Token : : Type : : Dimension ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <angle>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        float  angle_value  =  first_param . token ( ) . dimension_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  unit_string  =  first_param . token ( ) . dimension_unit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  angle_type  =  Angle : : unit_from_name ( unit_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! angle_type . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        gradient_direction  =  Angle  {  angle_value ,  angle_type . release_value ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( is_to_side_or_corner ( first_param ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <side-or-corner> = [left | right] || [top | bottom]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Note: -webkit-linear-gradient does not include to the "to" prefix on the side or corner
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( gradient_type  = =  GradientType : : Standard )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // [left | right] || [top | bottom]
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  first_side  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! first_side . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 12:36:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  side_a  =  to_side ( first_side . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Optional < SideOrCorner >  side_b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( tokens . has_next_token ( )  & &  tokens . peek_token ( ) . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            side_b  =  to_side ( tokens . next_token ( ) . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( side_a . has_value ( )  & &  ! side_b . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            gradient_direction  =  * side_a ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( side_a . has_value ( )  & &  side_b . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-09 14:53:53 -07:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Convert two sides to a corner
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( to_underlying ( * side_b )  <  to_underlying ( * side_a ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                swap ( side_a ,  side_b ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( side_a  = =  SideOrCorner : : Top  & &  side_b  = =  SideOrCorner : : Left ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                gradient_direction  =  SideOrCorner : : TopLeft ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else  if  ( side_a  = =  SideOrCorner : : Top  & &  side_b  = =  SideOrCorner : : Right ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                gradient_direction  =  SideOrCorner : : TopRight ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else  if  ( side_a  = =  SideOrCorner : : Bottom  & &  side_b  = =  SideOrCorner : : Left ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                gradient_direction  =  SideOrCorner : : BottomLeft ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else  if  ( side_a  = =  SideOrCorner : : Bottom  & &  side_b  = =  SideOrCorner : : Right ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                gradient_direction  =  SideOrCorner : : BottomRight ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        has_direction_param  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( has_direction_param  & &  ! tokens . next_token ( ) . is ( Token : : Type : : Comma ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 21:33:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  color_stops  =  parse_linear_color_stop_list ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! color_stops . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  LinearGradientStyleValue : : create ( gradient_direction ,  move ( * color_stops ) ,  gradient_type ,  repeating_gradient ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_conic_gradient_function ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! component_value . is_function ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-06 14:51:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    GradientRepeating  repeating_gradient  =  GradientRepeating : : No ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  function_name  =  component_value . function ( ) . name ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-06 14:51:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    function_name  =  consume_if_starts_with ( function_name ,  " repeating- " sv ,  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        repeating_gradient  =  GradientRepeating : : Yes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! function_name . equals_ignoring_ascii_case ( " conic-gradient " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  tokens  {  component_value . function ( ) . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Angle  from_angle ( 0 ,  Angle : : Type : : Deg ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    PositionValue  at_position  =  PositionValue : : center ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // conic-gradient( [ [ from <angle> ]? [ at <position> ]? ]  ||
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <color-interpolation-method> , <angular-color-stop-list> )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  got_from_angle  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  got_color_interpolation_method  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  got_at_position  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  consume_identifier  =  [ & ] ( auto  identifier )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  token_string  =  token . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( token_string . equals_ignoring_ascii_case ( identifier ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( consume_identifier ( " from " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // from <angle>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( got_from_angle  | |  got_at_position ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  angle_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! angle_token . is ( Token : : Type : : Dimension ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            float  angle  =  angle_token . token ( ) . dimension_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  angle_unit  =  angle_token . token ( ) . dimension_unit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  angle_type  =  Angle : : unit_from_name ( angle_unit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! angle_type . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            from_angle  =  Angle ( angle ,  * angle_type ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            got_from_angle  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( consume_identifier ( " at " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // at <position>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( got_at_position ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  position  =  parse_position ( tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! position . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            at_position  =  * position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            got_at_position  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( consume_identifier ( " in " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // <color-interpolation-method>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( got_color_interpolation_method ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln ( " FIXME: Parse color interpolation method for conic-gradient() " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            got_color_interpolation_method  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-05 21:40:46 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ( got_from_angle  | |  got_at_position  | |  got_color_interpolation_method )  & &  ! tokens . next_token ( ) . is ( Token : : Type : : Comma ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 21:33:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  color_stops  =  parse_angular_color_stop_list ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! color_stops . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  ConicGradientStyleValue : : create ( from_angle ,  at_position ,  move ( * color_stops ) ,  repeating_gradient ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-12 00:15:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_radial_gradient_function ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    using  EndingShape  =  RadialGradientStyleValue : : EndingShape ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    using  Extent  =  RadialGradientStyleValue : : Extent ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    using  CircleSize  =  RadialGradientStyleValue : : CircleSize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    using  EllipseSize  =  RadialGradientStyleValue : : EllipseSize ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    using  Size  =  RadialGradientStyleValue : : Size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! component_value . is_function ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-02 19:20:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  repeating_gradient  =  GradientRepeating : : No ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  function_name  =  component_value . function ( ) . name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-02 19:20:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    function_name  =  consume_if_starts_with ( function_name ,  " repeating- " sv ,  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        repeating_gradient  =  GradientRepeating : : Yes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! function_name . equals_ignoring_ascii_case ( " radial-gradient " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  tokens  {  component_value . function ( ) . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  expect_comma  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  commit_value  =  [ & ] < typename . . .  T > ( auto  value ,  T & . . .  transactions )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ( transactions . commit ( ) ,  . . . ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // radial-gradient( [ <ending-shape> || <size> ]? [ at <position> ]? , <color-stop-list> )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Size  size  =  Extent : : FarthestCorner ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    EndingShape  ending_shape  =  EndingShape : : Circle ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    PositionValue  at_position  =  PositionValue : : center ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_ending_shape  =  [ & ] ( )  - >  Optional < EndingShape >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! token . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  token . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " circle " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  commit_value ( EndingShape : : Circle ,  transaction ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " ellipse " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  commit_value ( EndingShape : : Ellipse ,  transaction ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_extent_keyword  =  [ ] ( StringView  keyword )  - >  Optional < Extent >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( keyword . equals_ignoring_ascii_case ( " closest-corner " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Extent : : ClosestCorner ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( keyword . equals_ignoring_ascii_case ( " closest-side " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Extent : : ClosestSide ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( keyword . equals_ignoring_ascii_case ( " farthest-corner " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Extent : : FarthestCorner ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( keyword . equals_ignoring_ascii_case ( " farthest-side " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Extent : : FarthestSide ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_size  =  [ & ] ( )  - >  Optional < Size >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <size> =
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //      <extent-keyword>              |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //      <length [0,∞]>                |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //      <length-percentage [0,∞]>{2}
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction_size  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  extent  =  parse_extent_keyword ( token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! extent . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  commit_value ( * extent ,  transaction_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  first_dimension  =  parse_dimension ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! first_dimension . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! first_dimension - > is_length_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction_second_dimension  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  second_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  second_dimension  =  parse_dimension ( second_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( second_dimension . has_value ( )  & &  second_dimension - > is_length_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  commit_value ( EllipseSize  {  first_dimension - > length_percentage ( ) ,  second_dimension - > length_percentage ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction_size ,  transaction_second_dimension ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first_dimension - > is_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  commit_value ( CircleSize  {  first_dimension - > length ( )  } ,  transaction_size ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // [ <ending-shape> || <size> ]?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_ending_shape  =  parse_ending_shape ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_size  =  parse_size ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_ending_shape . has_value ( )  & &  maybe_size . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            maybe_ending_shape  =  parse_ending_shape ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( maybe_size . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            size  =  * maybe_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            expect_comma  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( maybe_ending_shape . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            expect_comma  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ending_shape  =  * maybe_ending_shape ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ending_shape  = =  EndingShape : : Circle  & &  size . has < EllipseSize > ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ending_shape  = =  EndingShape : : Ellipse  & &  size . has < CircleSize > ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ending_shape  =  size . has < CircleSize > ( )  ?  EndingShape : : Circle  :  EndingShape : : Ellipse ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( token . is ( Token : : Type : : Ident )  & &  token . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " at " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  position  =  parse_position ( tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! position . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        at_position  =  * position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        expect_comma  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( expect_comma  & &  ! tokens . next_token ( ) . is ( Token : : Type : : Comma ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <color-stop-list>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  color_stops  =  parse_linear_color_stop_list ( tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! color_stops . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  RadialGradientStyleValue : : create ( ending_shape ,  size ,  at_position ,  move ( * color_stops ) ,  repeating_gradient ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 20:50:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < PositionValue >  Parser : : parse_position ( TokenStream < ComponentValue > &  tokens ,  PositionValue  initial_value )  
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_horizontal_preset  =  [ & ] ( auto  ident )  - >  Optional < PositionValue : : HorizontalPreset >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " left " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  PositionValue : : HorizontalPreset : : Left ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " center " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  PositionValue : : HorizontalPreset : : Center ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " right " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  PositionValue : : HorizontalPreset : : Right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_vertical_preset  =  [ & ] ( auto  ident )  - >  Optional < PositionValue : : VerticalPreset >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " top " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  PositionValue : : VerticalPreset : : Top ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " center " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  PositionValue : : VerticalPreset : : Center ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " bottom " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  PositionValue : : VerticalPreset : : Bottom ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_horizontal_edge  =  [ & ] ( auto  ident )  - >  Optional < PositionValue : : HorizontalEdge >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " left " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  PositionValue : : HorizontalEdge : : Left ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " right " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  PositionValue : : HorizontalEdge : : Right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_vertical_edge  =  [ & ] ( auto  ident )  - >  Optional < PositionValue : : VerticalEdge >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " top " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  PositionValue : : VerticalEdge : : Top ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " bottom " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  PositionValue : : VerticalEdge : : Bottom ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <position> = [
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   [ left | center | right ] || [ top | center | bottom ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   [ left | center | right | <length-percentage> ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   [ top | center | bottom | <length-percentage> ]?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   [ [ left | right ] <length-percentage> ] &&
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   [ [ top | bottom ] <length-percentage> ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // [ left | center | right ] || [ top | center | bottom ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  alternation_1  =  [ & ] ( )  - >  Optional < PositionValue >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 20:50:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        PositionValue  position  =  initial_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  first_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! first_token . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  first_token . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <horizontal-position> <vertical-position>?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  horizontal_position  =  parse_horizontal_preset ( ident ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( horizontal_position . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            position . horizontal_position  =  * horizontal_position ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 20:50:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  transaction_optional_parse  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  second_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 20:50:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( second_token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  vertical_position  =  parse_vertical_preset ( second_token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( vertical_position . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        transaction_optional_parse . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        position . vertical_position  =  * vertical_position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // <vertical-position> <horizontal-position>?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  vertical_position  =  parse_vertical_preset ( ident ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! vertical_position . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            position . vertical_position  =  * vertical_position ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 20:50:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  transaction_optional_parse  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  second_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 20:50:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( second_token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  horizontal_position  =  parse_horizontal_preset ( second_token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( horizontal_position . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        transaction_optional_parse . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        position . horizontal_position  =  * horizontal_position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // [ left | center | right | <length-percentage> ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // [ top | center | bottom | <length-percentage> ]?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  alternation_2  =  [ & ] ( )  - >  Optional < PositionValue >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 20:50:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        PositionValue  position  =  initial_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  first_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first_token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  horizontal_position  =  parse_horizontal_preset ( first_token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! horizontal_position . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            position . horizontal_position  =  * horizontal_position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  dimension  =  parse_dimension ( first_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! dimension . has_value ( )  | |  ! dimension - > is_length_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            position . horizontal_position  =  dimension - > length_percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 20:50:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction_optional_parse  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  second_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( second_token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  vertical_position  =  parse_vertical_preset ( second_token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 20:50:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( vertical_position . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction_optional_parse . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    position . vertical_position  =  * vertical_position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  dimension  =  parse_dimension ( second_token ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-08 20:50:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( dimension . has_value ( )  & &  dimension - > is_length_percentage ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction_optional_parse . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    position . vertical_position  =  dimension - > length_percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:23:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // [ [ left | right ] <length-percentage> ] &&
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // [ [ top | bottom ] <length-percentage> ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  alternation_3  =  [ & ] ( )  - >  Optional < PositionValue >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        PositionValue  position  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  parse_horizontal  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // [ left | right ] <length-percentage> ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  first_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! first_token . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  horizontal_egde  =  parse_horizontal_edge ( first_token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! horizontal_egde . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            position . x_relative_to  =  * horizontal_egde ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  second_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  dimension  =  parse_dimension ( second_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! dimension . has_value ( )  | |  ! dimension - > is_length_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            position . horizontal_position  =  dimension - > length_percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  parse_vertical  =  [ & ]  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // [ top | bottom ] <length-percentage> ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  first_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! first_token . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  vertical_edge  =  parse_vertical_edge ( first_token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! vertical_edge . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            position . y_relative_to  =  * vertical_edge ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  second_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  dimension  =  parse_dimension ( second_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! dimension . has_value ( )  | |  ! dimension - > is_length_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            position . vertical_position  =  dimension - > length_percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ( parse_horizontal ( )  & &  parse_vertical ( ) )  | |  ( parse_vertical ( )  & &  parse_horizontal ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: The alternatives must be attempted in this order since `alternation_2' can match a prefix of `alternation_3'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  position  =  alternation_3 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! position . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        position  =  alternation_2 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! position . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        position  =  alternation_1 ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( position . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 15:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								CSSRule *  Parser : : convert_to_rule ( NonnullRefPtr < Rule >  rule )  
						 
					
						
							
								
									
										
										
										
											2021-07-09 16:34:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 16:42:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( rule - > is_at_rule ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( has_ignored_vendor_prefix ( rule - > at_rule_name ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:22:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( rule - > at_rule_name ( ) . equals_ignoring_ascii_case ( " font-face " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-14 21:36:36 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! rule - > block ( )  | |  ! rule - > block ( ) - > is_curly ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " @font-face rule is malformed. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 17:42:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-29 15:51:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            TokenStream  tokens  {  rule - > block ( ) - > values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  parse_font_face_rule ( tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( rule - > at_rule_name ( ) . equals_ignoring_ascii_case ( " import " sv )  & &  ! rule - > prelude ( ) . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-13 00:33:23 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Optional < AK : : URL >  url ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto  const &  token  :  rule - > prelude ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 17:51:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( token . is ( Token : : Type : : Whitespace ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( token . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    url  =  m_context . complete_url ( token . token ( ) . string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 17:41:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    url  =  parse_url_function ( token ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 12:33:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 17:51:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // FIXME: Handle list of media queries. https://www.w3.org/TR/css-cascade-3/#conditional-import
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( url . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-06 16:05:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( url . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 22:47:47 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  CSSImportRule : : create ( url . value ( ) ,  const_cast < DOM : : Document & > ( * m_context . document ( ) ) ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 15:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Unable to parse url from @import rule " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( rule - > at_rule_name ( ) . equals_ignoring_ascii_case ( " media " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  media_query_tokens  =  TokenStream  {  rule - > prelude ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  media_query_list  =  parse_a_media_query_list ( media_query_tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( media_query_list . is_empty ( )  | |  ! rule - > block ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  child_tokens  =  TokenStream  {  rule - > block ( ) - > values ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:36:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  parser_rules  =  parse_a_list_of_rules ( child_tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-24 16:34:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            JS : : MarkedVector < CSSRule * >  child_rules ( m_context . realm ( ) . heap ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto &  raw_rule  :  parser_rules )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto *  child_rule  =  convert_to_rule ( raw_rule ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 15:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    child_rules . append ( child_rule ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-13 10:50:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  media_list  =  MediaList : : create ( m_context . realm ( ) ,  move ( media_query_list ) ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 23:03:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  rule_list  =  CSSRuleList : : create ( m_context . realm ( ) ,  child_rules ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-13 10:50:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  CSSMediaRule : : create ( m_context . realm ( ) ,  media_list ,  rule_list ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( rule - > at_rule_name ( ) . equals_ignoring_ascii_case ( " supports " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 17:48:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  supports_tokens  =  TokenStream  {  rule - > prelude ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  supports  =  parse_a_supports ( supports_tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! supports )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  constexpr  ( CSS_PARSER_DEBUG )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 16:16:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @supports rule invalid; discarding. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 17:48:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    supports_tokens . dump_all_tokens ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-11 17:42:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! rule - > block ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  child_tokens  =  TokenStream  {  rule - > block ( ) - > values ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-30 11:36:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  parser_rules  =  parse_a_list_of_rules ( child_tokens ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-24 16:34:04 -06:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            JS : : MarkedVector < CSSRule * >  child_rules ( m_context . realm ( ) . heap ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 17:48:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto &  raw_rule  :  parser_rules )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto *  child_rule  =  convert_to_rule ( raw_rule ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 15:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    child_rules . append ( child_rule ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-08 17:48:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 23:03:41 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  rule_list  =  CSSRuleList : : create ( m_context . realm ( ) ,  child_rules ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-14 20:03:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  CSSSupportsRule : : create ( m_context . realm ( ) ,  supports . release_nonnull ( ) ,  rule_list ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-06 16:05:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 23:30:54 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( rule - > at_rule_name ( ) . equals_ignoring_ascii_case ( " keyframes " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  prelude_stream  =  TokenStream  {  rule - > prelude ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            prelude_stream . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  token  =  prelude_stream . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! token . is_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes has invalid prelude, prelude = {}; discarding. " ,  rule - > prelude ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  name_token  =  token . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            prelude_stream . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( prelude_stream . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes has invalid prelude, prelude = {}; discarding. " ,  rule - > prelude ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( name_token . is ( Token : : Type : : Ident )  & &  ( is_builtin ( name_token . ident ( ) )  | |  name_token . ident ( ) . equals_ignoring_ascii_case ( " none " sv ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes rule name is invalid: {}; discarding. " ,  name_token . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! name_token . is ( Token : : Type : : String )  & &  ! name_token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes rule name is invalid: {}; discarding. " ,  name_token . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  name  =  name_token . to_string ( ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! rule - > block ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  child_tokens  =  TokenStream  {  rule - > block ( ) - > values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            Vector < JS : : NonnullGCPtr < CSSKeyframeRule > >  keyframes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            while  ( child_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                child_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // keyframe-selector = <keyframe-keyword> | <percentage>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // keyframe-keyword = "from" | "to"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // selector = <keyframe-selector>#
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // keyframes-block = "{" <declaration-list>? "}"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // keyframe-rule = <selector> <keyframes-block>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  selectors  =  Vector < CSS : : Percentage >  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                while  ( child_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    child_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! child_tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  tok  =  child_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! tok . is_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes rule has invalid selector: {}; discarding. " ,  tok . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        child_tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  token  =  tok . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  read_a_selector  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        if  ( token . ident ( ) . equals_ignoring_ascii_case ( " from " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            selectors . append ( CSS : : Percentage ( 0 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            read_a_selector  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        if  ( token . ident ( ) . equals_ignoring_ascii_case ( " to " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            selectors . append ( CSS : : Percentage ( 100 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            read_a_selector  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    }  else  if  ( token . is ( Token : : Type : : Percentage ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        selectors . append ( CSS : : Percentage ( token . percentage ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        read_a_selector  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( read_a_selector )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        child_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        if  ( child_tokens . next_token ( ) . is ( Token : : Type : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    child_tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! child_tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                child_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  token  =  child_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( token . is_block ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  block_tokens  =  token . block ( ) . values ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  block_stream  =  TokenStream  {  block_tokens  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  block_declarations  =  parse_a_list_of_declarations ( block_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  style  =  convert_to_style_declaration ( block_declarations ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    for  ( auto &  selector  :  selectors )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        auto  keyframe_rule  =  CSSKeyframeRule : : create ( m_context . realm ( ) ,  selector ,  * style ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        keyframes . append ( keyframe_rule ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @keyframes rule has invalid block: {}; discarding. " ,  token . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  CSSKeyframesRule : : create ( m_context . realm ( ) ,  name ,  move ( keyframes ) ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-06 16:05:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: More at rules!
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Unrecognized CSS at-rule: @{} " ,  rule - > at_rule_name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-06 16:05:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  prelude_stream  =  TokenStream ( rule - > prelude ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  selectors  =  parse_a_selector_list ( prelude_stream ,  SelectorType : : Standalone ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 17:47:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( selectors . is_error ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( selectors . error ( )  = =  ParseError : : SyntaxError )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: style rule selectors invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  constexpr  ( CSS_PARSER_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                prelude_stream . dump_all_tokens ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 17:47:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( selectors . value ( ) . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: empty selector; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! rule - > block ( ) - > is_curly ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  stream  =  TokenStream ( rule - > block ( ) - > values ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  declarations_and_at_rules  =  parse_a_style_blocks_contents ( stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-23 16:13:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto *  declaration  =  convert_to_style_declaration ( declarations_and_at_rules ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! declaration )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: style rule declaration invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 23:38:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  CSSStyleRule : : create ( m_context . realm ( ) ,  move ( selectors . value ( ) ) ,  * declaration ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 16:34:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:01:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								auto  Parser : : extract_properties ( Vector < DeclarationOrAtRule >  const &  declarations_and_at_rules )  - >  PropertiesAndCustomProperties  
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:01:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    PropertiesAndCustomProperties  result ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  declaration_or_at_rule  :  declarations_and_at_rules )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( declaration_or_at_rule . is_at_rule ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " !!! CSS at-rule is not allowed here! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:01:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  declaration  =  declaration_or_at_rule . declaration ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:01:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_property  =  convert_to_style_property ( declaration ) ;  maybe_property . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  property  =  maybe_property . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( property . property_id  = =  PropertyID : : Custom )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:01:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                result . custom_properties . set ( property . custom_name ,  property ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:01:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                result . properties . append ( move ( property ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:01:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  result ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-03-28 16:37:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:51:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								PropertyOwningCSSStyleDeclaration *  Parser : : convert_to_style_declaration ( Vector < DeclarationOrAtRule >  const &  declarations_and_at_rules )  
						 
					
						
							
								
									
										
										
										
											2022-03-29 16:01:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  [ properties ,  custom_properties ]  =  extract_properties ( declarations_and_at_rules ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-12 23:22:53 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  PropertyOwningCSSStyleDeclaration : : create ( m_context . realm ( ) ,  move ( properties ) ,  move ( custom_properties ) ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-06 16:32:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 14:36:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < StyleProperty >  Parser : : convert_to_style_property ( Declaration  const &  declaration )  
						 
					
						
							
								
									
										
										
										
											2021-07-06 16:32:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-12 16:09:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  property_name  =  declaration . name ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-06 16:32:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  property_id  =  property_id_from_string ( property_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-10 13:01:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! property_id . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( property_name . starts_with ( " -- " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 16:49:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            property_id  =  PropertyID : : Custom ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( has_ignored_vendor_prefix ( property_name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 20:10:18 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( ! property_name . starts_with ( ' - ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 16:16:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Unrecognized CSS property '{}' " ,  property_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 16:49:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-06 16:32:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 14:41:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  value_token_stream  =  TokenStream ( declaration . values ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-10 13:01:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  value  =  parse_css_value ( property_id . value ( ) ,  value_token_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value . is_error ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value . error ( )  = =  ParseError : : SyntaxError )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 16:16:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Unable to parse value for CSS property '{}'. " ,  property_name ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-22 20:33:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  constexpr  ( CSS_PARSER_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                value_token_stream . dump_all_tokens ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-06 16:32:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-10 13:01:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( property_id . value ( )  = =  PropertyID : : Custom ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  StyleProperty  {  declaration . importance ( ) ,  property_id . value ( ) ,  value . release_value ( ) ,  declaration . name ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-10 13:01:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  StyleProperty  {  declaration . importance ( ) ,  property_id . value ( ) ,  value . release_value ( ) ,  { }  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_builtin_value ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  component_value . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " inherit " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  InheritStyleValue : : the ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " initial " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  InitialStyleValue : : the ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " unset " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  UnsetStyleValue : : the ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-20 19:52:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Implement `revert` and `revert-layer` keywords, from Cascade4 and Cascade5 respectively
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-19 15:45:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < CalculatedStyleValue > >  Parser : : parse_calculated_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2022-01-25 14:45:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  calculation_tree  =  TRY ( parse_a_calculation ( component_values ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( calculation_tree  = =  nullptr )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to parse calculation tree " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 14:45:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  constexpr  ( CSS_PARSER_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln ( " Parsed calculation tree: " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            StringBuilder  builder ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( calculation_tree - > dump ( builder ,  0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln ( builder . string_view ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 14:45:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 16:29:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  calc_type  =  calculation_tree - > determine_type ( m_context . current_property_id ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 14:45:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! calc_type . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 16:16:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " calc() resolved as invalid!!! " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 14:45:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 16:29:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    dbgln_if ( CSS_PARSER_DEBUG ,  " Deduced calc() resolved type as: {} " ,  calc_type - > dump ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 14:45:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  CalculatedStyleValue : : create ( calculation_tree . release_nonnull ( ) ,  calc_type . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-25 14:45:08 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 11:21:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_min_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  stream  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parameters  =  parse_a_comma_separated_list_of_component_values ( stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parameters . size ( )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " min() must have at least 1 parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < NonnullOwnPtr < CalculationNode > >  calculated_parameters ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    calculated_parameters . ensure_capacity ( parameters . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    CalculatedStyleValue : : ResolvedType  type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  first  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  parameter  :  parameters )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  calculation_node  =  TRY ( parse_a_calculation ( parameter ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " min() parameters must be valid calculations " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:59:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  parameter_type  =  calculation_node - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for min() parameter #{} " sv ,  calculated_parameters . size ( )  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 11:21:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:59:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            type  =  parameter_type . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 11:21:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            first  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:59:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( parameter_type  ! =  type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 11:21:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " min() parameters must all be of the same type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        calculated_parameters . append ( calculation_node . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( MinCalculationNode : : create ( move ( calculated_parameters ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 15:00:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_max_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  stream  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parameters  =  parse_a_comma_separated_list_of_component_values ( stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parameters . size ( )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " max() must have at least 1 parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < NonnullOwnPtr < CalculationNode > >  calculated_parameters ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    calculated_parameters . ensure_capacity ( parameters . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    CalculatedStyleValue : : ResolvedType  type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  first  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  parameter  :  parameters )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  calculation_node  =  TRY ( parse_a_calculation ( parameter ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " max() parameters must be valid calculations " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:59:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  parameter_type  =  calculation_node - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for max() parameter #{} " sv ,  calculated_parameters . size ( )  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 15:00:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:59:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            type  =  parameter_type . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 15:00:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            first  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:59:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( parameter_type  ! =  type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 15:00:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " max() parameters must all be of the same type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        calculated_parameters . append ( calculation_node . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( MaxCalculationNode : : create ( move ( calculated_parameters ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 15:40:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_clamp_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  stream  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parameters  =  parse_a_comma_separated_list_of_component_values ( stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parameters . size ( )  ! =  3 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " clamp() must have exactly three parameters " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < NonnullOwnPtr < CalculationNode > >  calculated_parameters ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    calculated_parameters . ensure_capacity ( parameters . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    CalculatedStyleValue : : ResolvedType  type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  first  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  parameter  :  parameters )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  calculation_node  =  TRY ( parse_a_calculation ( parameter ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " clamp() parameters must be valid calculations " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:59:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  parameter_type  =  calculation_node - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for clamp() parameter #{} " sv ,  calculated_parameters . size ( )  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 15:40:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:59:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            type  =  parameter_type . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 15:40:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            first  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:59:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( parameter_type  ! =  type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 15:40:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " clamp() parameters must all be of same type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        calculated_parameters . append ( calculation_node . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( ClampCalculationNode : : create ( move ( calculated_parameters [ 0 ] ) ,  move ( calculated_parameters [ 1 ] ) ,  move ( calculated_parameters [ 2 ] ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 22:56:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_abs_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  calculation_node  =  TRY ( parse_a_calculation ( function . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " abs() parameter must be a valid calculation " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( AbsCalculationNode : : create ( calculation_node . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 23:02:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_sign_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  calculation_node  =  TRY ( parse_a_calculation ( function . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " sign() parameter must be a valid calculation " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( SignCalculationNode : : create ( calculation_node . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 23:50:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_sin_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  calculation_node  =  TRY ( parse_a_calculation ( function . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " sin() parameter must be a valid calculation " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_parameter_type  =  calculation_node - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for sin() parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  resolved_type  =  maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Number  & &  resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Angle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " sin() parameter must be a number or angle " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( SinCalculationNode : : create ( calculation_node . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 23:57:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_cos_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  calculation_node  =  TRY ( parse_a_calculation ( function . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " cos() parameter must be a valid calculation " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_parameter_type  =  calculation_node - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for cos() parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  resolved_type  =  maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Number  & &  resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Angle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " cos() parameter must be a number or angle " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( CosCalculationNode : : create ( calculation_node . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 00:02:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_tan_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  calculation_node  =  TRY ( parse_a_calculation ( function . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " tan() parameter must be a valid calculation " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_parameter_type  =  calculation_node - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for tan() parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  resolved_type  =  maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Number  & &  resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Angle )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " tan() parameter must be a number or angle " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( TanCalculationNode : : create ( calculation_node . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 10:55:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_asin_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  calculation_node  =  TRY ( parse_a_calculation ( function . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " asin() parameter must be a valid calculation " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_parameter_type  =  calculation_node - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for asin() parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  resolved_type  =  maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " asin() parameter must be a number " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( AsinCalculationNode : : create ( calculation_node . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:00:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_acos_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  calculation_node  =  TRY ( parse_a_calculation ( function . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " acos() parameter must be a valid calculation " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_parameter_type  =  calculation_node - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for acos() parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  resolved_type  =  maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " acos() parameter must be a number " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( AcosCalculationNode : : create ( calculation_node . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:04:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_atan_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  calculation_node  =  TRY ( parse_a_calculation ( function . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " atan() parameter must be a valid calculation " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_parameter_type  =  calculation_node - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for atan() parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  resolved_type  =  maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " atan() parameter must be a number " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( AtanCalculationNode : : create ( calculation_node . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:19:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_atan2_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  stream  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parameters  =  parse_a_comma_separated_list_of_component_values ( stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parameters . size ( )  ! =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " atan2() must have exactly two parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a  =  TRY ( parse_a_calculation ( parameters [ 0 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b  =  TRY ( parse_a_calculation ( parameters [ 1 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a  | |  ! node_b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " atan2() parameters must be valid calculations " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_maybe_parameter_type  =  node_a - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:26:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for atan2() parameter 1 " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:19:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_maybe_parameter_type  =  node_b - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_b_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:26:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for atan2() parameter 2 " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:19:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_resolved_type  =  node_a_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_resolved_type  =  node_b_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( node_a_resolved_type  ! =  node_b_resolved_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " atan2() parameters must be of the same type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( Atan2CalculationNode : : create ( node_a . release_nonnull ( ) ,  node_b . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:26:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_pow_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  stream  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parameters  =  parse_a_comma_separated_list_of_component_values ( stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parameters . size ( )  ! =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " pow() must have exactly two parameters " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a  =  TRY ( parse_a_calculation ( parameters [ 0 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b  =  TRY ( parse_a_calculation ( parameters [ 1 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a  | |  ! node_b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " pow() parameters must be valid calculations " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_maybe_parameter_type  =  node_a - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for pow() parameter 1 " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_maybe_parameter_type  =  node_b - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_b_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for pow() parameter 2 " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_resolved_type  =  node_a_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_resolved_type  =  node_b_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( node_a_resolved_type  ! =  node_b_resolved_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " pow() parameters must be of the same type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( node_a_resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " pow() parameters must be numbers " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( PowCalculationNode : : create ( node_a . release_nonnull ( ) ,  node_b . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:31:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_sqrt_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node  =  TRY ( parse_a_calculation ( function . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " sqrt() parameter must be valid calculation " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_parameter_type  =  node - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for sqrt() parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  resolved_type  =  maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Number ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Error : : from_string_view ( " sqrt() parameter must be number " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( SqrtCalculationNode : : create ( node . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:43:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_hypot_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  stream  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parameters  =  parse_a_comma_separated_list_of_component_values ( stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parameters . size ( )  = =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " hypot() must have at least 1 parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < NonnullOwnPtr < CalculationNode > >  calculated_parameters ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    calculated_parameters . ensure_capacity ( parameters . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    CalculatedStyleValue : : ResolvedType  type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  first  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  parameter  :  parameters )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  calculation_node  =  TRY ( parse_a_calculation ( parameter ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! calculation_node )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " hypot() parameters must be valid calculations " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_parameter_type  =  calculation_node - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for hypot() parameter #{} " sv ,  calculated_parameters . size ( )  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  resolved_type  =  maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            type  =  resolved_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            first  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( resolved_type  ! =  type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " hypot() parameters must all be of the same type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        calculated_parameters . append ( calculation_node . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( HypotCalculationNode : : create ( move ( calculated_parameters ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:53:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_log_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  stream  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parameters  =  parse_a_comma_separated_list_of_component_values ( stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    OwnPtr < CalculationNode >  node_b ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parameters . size ( )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        node_b  =  TRY ( ConstantCalculationNode : : create ( CalculationNode : : ConstantType : : E ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( parameters . size ( )  = =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        node_b  =  TRY ( parse_a_calculation ( parameters [ 1 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " log() must have exactly one or two parameters " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a  =  TRY ( parse_a_calculation ( parameters [ 0 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a  | |  ! node_b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " log() parameters must be valid calculations " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_maybe_parameter_type  =  node_a - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for log() parameter 1 " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_maybe_parameter_type  =  node_b - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_b_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for log() parameter 2 " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_resolved_type  =  node_a_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_resolved_type  =  node_b_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( node_a_resolved_type  ! =  node_b_resolved_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " log() parameters must be of the same type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( node_a_resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " log() parameters must be numbers " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( LogCalculationNode : : create ( node_a . release_nonnull ( ) ,  node_b . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:58:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_exp_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a  =  TRY ( parse_a_calculation ( function . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " exp() parameter must be valid calculation " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_parameter_type  =  node_a - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for exp() parameter " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  resolved_type  =  maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( resolved_type  ! =  CalculatedStyleValue : : ResolvedType : : Number )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " exp() parameter must be number " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( ExpCalculationNode : : create ( node_a . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 16:07:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_round_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  stream  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parameters  =  parse_a_comma_separated_list_of_component_values ( stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parameters . size ( )  ! =  2  & &  parameters . size ( )  ! =  3 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " round() must have exactly two or three parameters " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    OwnPtr < CalculationNode >  node_a  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    OwnPtr < CalculationNode >  node_b  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-13 14:51:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  strategy  =  RoundingStrategy : : Nearest ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 16:07:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parameters . size ( )  = =  3 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-13 14:51:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  rounding_strategy_component  =  parameters [ 0 ] [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! rounding_strategy_component . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " round() strategy must be an ident " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 16:07:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-13 14:51:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_value_id  =  value_id_from_string ( rounding_strategy_component . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_value_id . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " round() strategy must be one of 'nearest', 'up', 'down', or 'to-zero' " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_strategy  =  value_id_to_rounding_strategy ( maybe_value_id . value ( ) ) ;  maybe_strategy . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            strategy  =  maybe_strategy . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 16:07:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-13 14:51:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " round() strategy must be one of 'nearest', 'up', 'down', or 'to-zero' " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 16:07:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        node_a  =  TRY ( parse_a_calculation ( parameters [ 1 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        node_b  =  TRY ( parse_a_calculation ( parameters [ 2 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        node_a  =  TRY ( parse_a_calculation ( parameters [ 0 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        node_b  =  TRY ( parse_a_calculation ( parameters [ 1 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a  | |  ! node_b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " round() parameters must be valid calculations " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_maybe_parameter_type  =  node_a - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for round() parameter 1 " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_maybe_parameter_type  =  node_b - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_b_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for round() parameter 2 " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_resolved_type  =  node_a_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_resolved_type  =  node_b_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( node_a_resolved_type  ! =  node_b_resolved_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " round() parameters must all be of the same type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-13 14:51:11 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( RoundCalculationNode : : create ( strategy ,  node_a . release_nonnull ( ) ,  node_b . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 16:07:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 19:03:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_mod_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  stream  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parameters  =  parse_a_comma_separated_list_of_component_values ( stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parameters . size ( )  ! =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " mod() must have exactly two parameters " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a  =  TRY ( parse_a_calculation ( parameters [ 0 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b  =  TRY ( parse_a_calculation ( parameters [ 1 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a  | |  ! node_b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " mod() parameters must be valid calculations " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_maybe_parameter_type  =  node_a - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for mod() parameter 1 " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_maybe_parameter_type  =  node_b - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_b_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for mod() parameter 2 " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_resolved_type  =  node_a_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_resolved_type  =  node_b_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( node_a_resolved_type  ! =  node_b_resolved_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " mod() parameters must all be of the same type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( ModCalculationNode : : create ( node_a . release_nonnull ( ) ,  node_b . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 19:08:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_rem_function ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  stream  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parameters  =  parse_a_comma_separated_list_of_component_values ( stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parameters . size ( )  ! =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " rem() must have exactly two parameters " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a  =  TRY ( parse_a_calculation ( parameters [ 0 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b  =  TRY ( parse_a_calculation ( parameters [ 1 ] ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a  | |  ! node_b )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " rem() parameters must be valid calculations " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_maybe_parameter_type  =  node_a - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_a_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for rem() parameter 1 " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_maybe_parameter_type  =  node_b - > resolved_type ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! node_b_maybe_parameter_type . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Failed to resolve type for rem() parameter 2 " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_a_resolved_type  =  node_a_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  node_b_resolved_type  =  node_b_maybe_parameter_type . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( node_a_resolved_type  ! =  node_b_resolved_type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " rem() parameters must all be of the same type " sv ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  TRY ( RemCalculationNode : : create ( node_a . release_nonnull ( ) ,  node_b . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_dynamic_value ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2021-08-19 15:45:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is_function ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  function  =  component_value . function ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( function . name ( ) . equals_ignoring_ascii_case ( " var " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-03 20:17:17 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Declarations using `var()` should already be parsed as an UnresolvedStyleValue before this point.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 20:56:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  function_node  =  TRY ( parse_a_calc_function_node ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! function_node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 16:29:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  function_type  =  function_node - > determine_type ( m_context . current_property_id ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:59:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! function_type . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  CalculatedStyleValue : : create ( function_node . release_nonnull ( ) ,  function_type . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 20:56:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_a_calc_function_node ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " calc " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_a_calculation ( function . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 11:21:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " min " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_min_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 15:00:22 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " max " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_max_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 15:40:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " clamp " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_clamp_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 22:56:41 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " abs " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_abs_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 23:02:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " sign " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_sign_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 23:50:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " sin " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_sin_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 23:57:01 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " cos " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_cos_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 00:02:43 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " tan " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_tan_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 10:55:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " asin " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_asin_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:00:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " acos " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_acos_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:04:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " atan " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_atan_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:19:10 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " atan2 " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_atan2_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:26:42 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " pow " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_pow_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:31:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " sqrt " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_sqrt_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:43:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " hypot " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_hypot_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:53:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " log " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_log_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-28 11:58:30 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " exp " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_exp_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 16:07:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " round " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_round_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 19:03:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " mod " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_mod_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 19:08:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " rem " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( parse_rem_function ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 20:56:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Parser : : Dimension >  Parser : : parse_dimension ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is ( Token : : Type : : Dimension ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        float  numeric_value  =  component_value . token ( ) . dimension_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-18 12:04:05 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  unit_string  =  component_value . token ( ) . dimension_unit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:10:48 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  length_type  =  Length : : unit_from_name ( unit_string ) ;  length_type . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Length  {  numeric_value ,  length_type . release_value ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  angle_type  =  Angle : : unit_from_name ( unit_string ) ;  angle_type . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Angle  {  numeric_value ,  angle_type . release_value ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  frequency_type  =  Frequency : : unit_from_name ( unit_string ) ;  frequency_type . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Frequency  {  numeric_value ,  frequency_type . release_value ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  resolution_type  =  Resolution : : unit_from_name ( unit_string ) ;  resolution_type . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Resolution  {  numeric_value ,  resolution_type . release_value ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  time_type  =  Time : : unit_from_name ( unit_string ) ;  time_type . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Time  {  numeric_value ,  time_type . release_value ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is ( Token : : Type : : Percentage ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Percentage  {  static_cast < float > ( component_value . token ( ) . percentage ( ) )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is ( Token : : Type : : Number ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        float  numeric_value  =  component_value . token ( ) . number_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( numeric_value  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Length : : make_px ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( m_context . in_quirks_mode ( )  & &  property_has_quirk ( m_context . current_property_id ( ) ,  Quirk : : UnitlessLength ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 20:48:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // https://quirks.spec.whatwg.org/#quirky-length-value
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: Disallow quirk when inside a CSS sub-expression (like `calc()`)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // "The <quirky-length> value must not be supported in arguments to CSS expressions other than the rect()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // expression, and must not be supported in the supports() static method of the CSS interface."
 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Length : : make_px ( numeric_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Length >  Parser : : parse_length ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  dimension  =  parse_dimension ( component_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! dimension . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( dimension - > is_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  dimension - > length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Ratio >  Parser : : parse_ratio ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2022-03-06 13:48:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 13:48:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:59:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  read_number_value  =  [ this ] ( ComponentValue  const &  component_value )  - >  Optional < float >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( component_value . is ( Token : : Type : : Number ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  component_value . token ( ) . number_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( component_value . is_function ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_calc  =  parse_dynamic_value ( component_value ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_calc  | |  ! maybe_calc - > is_calculated ( )  | |  ! maybe_calc - > as_calculated ( ) . resolves_to_number ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  resolved_number  =  maybe_calc - > as_calculated ( ) . resolve_number ( ) ;  resolved_number . has_value ( )  & &  resolved_number . value ( )  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  resolved_number . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 13:48:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // `<ratio> = <number [0,∞]> [ / <number [0,∞]> ]?`
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:59:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_numerator  =  read_number_value ( tokens . next_token ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_numerator . has_value ( )  | |  maybe_numerator . value ( )  <  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:59:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  numerator  =  maybe_numerator . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 13:48:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  two_value_transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  solidus  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:59:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_denominator  =  read_number_value ( tokens . next_token ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( solidus . is_delim ( ' / ' )  & &  maybe_denominator . has_value ( )  & &  maybe_denominator . value ( )  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  denominator  =  maybe_denominator . value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Two-value ratio
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            two_value_transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:59:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Ratio  {  numerator ,  denominator  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 13:48:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Single-value ratio
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:59:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  Ratio  {  numerator  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 13:48:32 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-syntax-3/#urange-syntax
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Optional < UnicodeRange >  Parser : : parse_unicode_range ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <urange> =
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u '+' <ident-token> '?'* |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u <dimension-token> '?'* |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u <number-token> '?'* |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u <number-token> <dimension-token> |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u <number-token> <number-token> |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u '+' '?'+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // (All with no whitespace in between tokens.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: Parsing this is different from usual. We take these steps:
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Match the grammar above against the tokens, concatenating them into a string using their original representation.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. Then, parse that string according to the spec algorithm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Step 2 is performed by calling the other parse_unicode_range() overload.
 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_ending_token  =  [ ] ( ComponentValue  const &  component_value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  component_value . is ( Token : : Type : : EndOfFile ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            | |  component_value . is ( Token : : Type : : Comma ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            | |  component_value . is ( Token : : Type : : Semicolon ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            | |  component_value . is ( Token : : Type : : Whitespace ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  create_unicode_range  =  [ & ] ( StringView  text ,  auto &  local_transaction )  - >  Optional < UnicodeRange >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_unicode_range  =  parse_unicode_range ( text ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( maybe_unicode_range . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            local_transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  maybe_unicode_range ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // All options start with 'u'/'U'.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  u  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! ( u . is ( Token : : Type : : Ident )  & &  u . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " u " sv ) ) )  { 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: <urange> does not start with 'u' " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  second_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u '+' <ident-token> '?'* |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u '+' '?'+
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( second_token . is_delim ( ' + ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  local_transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        StringBuilder  string_builder ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-22 15:26:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        string_builder . append ( second_token . token ( ) . representation ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  third_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( third_token . is ( Token : : Type : : Ident )  | |  third_token . is_delim ( ' ? ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-22 15:26:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            string_builder . append ( third_token . token ( ) . representation ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            while  ( tokens . peek_token ( ) . is_delim ( ' ? ' ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-22 15:26:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                string_builder . append ( tokens . next_token ( ) . token ( ) . representation ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is_ending_token ( tokens . peek_token ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  create_unicode_range ( string_builder . string_view ( ) ,  local_transaction ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u <dimension-token> '?'*
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( second_token . is ( Token : : Type : : Dimension ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  local_transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        StringBuilder  string_builder ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-22 15:26:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        string_builder . append ( second_token . token ( ) . representation ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        while  ( tokens . peek_token ( ) . is_delim ( ' ? ' ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-22 15:26:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            string_builder . append ( tokens . next_token ( ) . token ( ) . representation ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_ending_token ( tokens . peek_token ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  create_unicode_range ( string_builder . string_view ( ) ,  local_transaction ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u <number-token> '?'* |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u <number-token> <dimension-token> |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  u <number-token> <number-token>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( second_token . is ( Token : : Type : : Number ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  local_transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        StringBuilder  string_builder ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-22 15:26:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        string_builder . append ( second_token . token ( ) . representation ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_ending_token ( tokens . peek_token ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  create_unicode_range ( string_builder . string_view ( ) ,  local_transaction ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  third_token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( third_token . is_delim ( ' ? ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-22 15:26:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            string_builder . append ( third_token . token ( ) . representation ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            while  ( tokens . peek_token ( ) . is_delim ( ' ? ' ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-22 15:26:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                string_builder . append ( tokens . next_token ( ) . token ( ) . representation ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is_ending_token ( tokens . peek_token ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  create_unicode_range ( string_builder . string_view ( ) ,  local_transaction ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( third_token . is ( Token : : Type : : Dimension ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-22 15:26:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            string_builder . append ( third_token . token ( ) . representation ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is_ending_token ( tokens . peek_token ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  create_unicode_range ( string_builder . string_view ( ) ,  local_transaction ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( third_token . is ( Token : : Type : : Number ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-22 15:26:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            string_builder . append ( third_token . token ( ) . representation ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is_ending_token ( tokens . peek_token ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  create_unicode_range ( string_builder . string_view ( ) ,  local_transaction ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  constexpr  ( CSS_PARSER_DEBUG )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln ( " CSSParser: Tokens did not match <urange> grammar. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . dump_all_tokens ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < UnicodeRange >  Parser : : parse_unicode_range ( StringView  text )  
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  make_valid_unicode_range  =  [ & ] ( u32  start_value ,  u32  end_value )  - >  Optional < UnicodeRange >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://www.w3.org/TR/css-syntax-3/#maximum-allowed-code-point
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        constexpr  u32  maximum_allowed_code_point  =  0x10FFFF ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // To determine what codepoints the <urange> represents:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. If end value is greater than the maximum allowed code point,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    the <urange> is invalid and a syntax error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( end_value  >  maximum_allowed_code_point )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Invalid <urange>: end_value ({}) > maximum ({}) " ,  end_value ,  maximum_allowed_code_point ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If start value is greater than end value, the <urange> is invalid and a syntax error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( start_value  >  end_value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Invalid <urange>: start_value ({}) > end_value ({}) " ,  start_value ,  end_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. Otherwise, the <urange> represents a contiguous range of codepoints from start value to end value, inclusive.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  UnicodeRange  {  start_value ,  end_value  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Skipping the first u token, concatenate the representations of all the tokens in the production together.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    Let this be text.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: The concatenation is already done by the caller.
 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    GenericLexer  lexer  {  text  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2. If the first character of text is U+002B PLUS SIGN, consume it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    Otherwise, this is an invalid <urange>, and this algorithm must exit.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( lexer . next_is ( ' + ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        lexer . consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Second character of <urange> was not '+'; got: '{}' " ,  lexer . consume ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Consume as many hex digits from text as possible.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    then consume as many U+003F QUESTION MARK (?) code points as possible.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  hex_digits  =  lexer . consume_while ( is_ascii_hex_digit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  question_marks  =  lexer . consume_while ( [ ] ( auto  it )  {  return  it  = =  ' ? ' ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    If zero code points were consumed, or more than six code points were consumed,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    this is an invalid <urange>, and this algorithm must exit.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    size_t  consumed_code_points  =  hex_digits . length ( )  +  question_marks . length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( consumed_code_points  = =  0  | |  consumed_code_points  >  6 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: <urange> start value had {} digits/?s, expected between 1 and 6. " ,  consumed_code_points ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StringView  start_value_code_points  {  hex_digits . characters_without_null_termination ( ) ,  consumed_code_points  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    If any U+003F QUESTION MARK (?) code points were consumed, then:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( question_marks . length ( )  >  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. If there are any code points left in text, this is an invalid <urange>,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    and this algorithm must exit.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( lexer . tell_remaining ( )  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: <urange> invalid; had {} code points left over. " ,  lexer . tell_remaining ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. Interpret the consumed code points as a hexadecimal number,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    with the U+003F QUESTION MARK (?) code points replaced by U+0030 DIGIT ZERO (0) code points.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    This is the start value.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  start_value_string  =  start_value_code_points . replace ( " ? " sv ,  " 0 " sv ,  ReplaceMode : : All ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_start_value  =  AK : : StringUtils : : convert_to_uint_from_hex < u32 > ( start_value_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_start_value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: <urange> ?-converted start value did not parse as hex number. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        u32  start_value  =  maybe_start_value . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. Interpret the consumed code points as a hexadecimal number again,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    with the U+003F QUESTION MARK (?) code points replaced by U+0046 LATIN CAPITAL LETTER F (F) code points.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    This is the end value.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  end_value_string  =  start_value_code_points . replace ( " ? " sv ,  " F " sv ,  ReplaceMode : : All ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_end_value  =  AK : : StringUtils : : convert_to_uint_from_hex < u32 > ( end_value_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_end_value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: <urange> ?-converted end value did not parse as hex number. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        u32  end_value  =  maybe_end_value . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 4. Exit this algorithm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  make_valid_unicode_range ( start_value ,  end_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   Otherwise, interpret the consumed code points as a hexadecimal number. This is the start value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_start_value  =  AK : : StringUtils : : convert_to_uint_from_hex < u32 > ( start_value_code_points ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_start_value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: <urange> start value did not parse as hex number. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    u32  start_value  =  maybe_start_value . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. If there are no code points left in text, The end value is the same as the start value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    Exit this algorithm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( lexer . tell_remaining ( )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  make_valid_unicode_range ( start_value ,  start_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. If the next code point in text is U+002D HYPHEN-MINUS (-), consume it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( lexer . next_is ( ' - ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        lexer . consume ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    Otherwise, this is an invalid <urange>, and this algorithm must exit.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: <urange> start and end values not separated by '-'. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 6. Consume as many hex digits as possible from text.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  end_hex_digits  =  lexer . consume_while ( is_ascii_hex_digit ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   If zero hex digits were consumed, or more than 6 hex digits were consumed,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   this is an invalid <urange>, and this algorithm must exit.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( end_hex_digits . length ( )  = =  0  | |  end_hex_digits . length ( )  >  6 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: <urange> end value had {} digits, expected between 1 and 6. " ,  end_hex_digits . length ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //   If there are any code points left in text, this is an invalid <urange>, and this algorithm must exit.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( lexer . tell_remaining ( )  ! =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: <urange> invalid; had {} code points left over. " ,  lexer . tell_remaining ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 7. Interpret the consumed code points as a hexadecimal number. This is the end value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_end_value  =  AK : : StringUtils : : convert_to_uint_from_hex < u32 > ( end_hex_digits ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_end_value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: <urange> end value did not parse as hex number. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 19:56:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Parse `<urange>` as CSS::UnicodeRange
Like, An+B, this is an old construct that does not fit well with modern
CSS syntax, so things get a bit hairy! We have to determine which
tokens match the grammar for `<urange>`, then turn those back into a
string, and then parse the string differently from normal. Thankfully
the spec describes in detail how to do that. :^)
This is not 100% correct, since we are not using the original source
text (referred to in the spec as the "representation") of the tokens,
but just converting them to strings in a manual, ad-hoc way.
Re-engineering the Tokenizer to keep that original text was too much of
a tangent for today. In any case, we do parse `U+4???`, `U+0-100`,
`U+1234`, and similar, so good enough for now!
											 
										 
										
											2022-04-07 17:41:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    u32  end_value  =  maybe_end_value . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  make_valid_unicode_range ( start_value ,  end_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_dimension_value ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
											 
										
											
												LibWeb: Make '0' always be both a number and a length in CSS
A '0' token can be interpreted both as a Number, and as a Length. This
is problematic as in our CSS parser, we often call parse_css_value()
first, to figure out what something is, and then assign it. So we do not
know in advance whether we want a Length or not. Previously, it always
got parsed as a Length, and then every place that expected a
NumericStyleValue had to also check for a Length(0), which is easy to
forget to do.
In particular, this was causing issues with the `flex` property parsing.
To solve this, we now always parse 0 as a NumericStyleValue, and NSVs of
0 pretend to be a Length(0px) when asked. In two places, we were casting
to a LengthStyleValue* based on is_length(), which no longer works, so
those have been adjusted to use `StyleValue::to_length()` instead. They
also now check for `is_numeric()` first, to avoid the extra conversion
to a Length and back.
Possibly this opens up new issues elsewhere. In my testing it seems
fine, but until we can get CSS test suites running, it's hard to know
for certain.
											 
										 
										
											2021-08-05 15:26:04 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Numbers with no units can be lengths, in two situations:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1) We're in quirks mode, and it's an integer.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 2) It's a 0.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // We handle case 1 here. Case 2 is handled by NumericStyleValue pretending to be a LengthStyleValue if it is 0.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 16:02:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 03:54:05 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is ( Token : : Type : : Number )  & &  component_value . token ( ) . number_value ( )  ! =  0  & &  ! ( m_context . in_quirks_mode ( )  & &  property_has_quirk ( m_context . current_property_id ( ) ,  Quirk : : UnitlessLength ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  dimension  =  parse_dimension ( component_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! dimension . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( dimension - > is_angle ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  AngleStyleValue : : create ( dimension - > angle ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( dimension - > is_frequency ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  FrequencyStyleValue : : create ( dimension - > frequency ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( dimension - > is_length ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  LengthStyleValue : : create ( dimension - > length ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( dimension - > is_percentage ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  PercentageStyleValue : : create ( dimension - > percentage ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( dimension - > is_resolution ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ResolutionStyleValue : : create ( dimension - > resolution ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( dimension - > is_time ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  TimeStyleValue : : create ( dimension - > time ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:01:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_integer_value ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:01:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  peek_token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( peek_token . is ( Token : : Type : : Number )  & &  peek_token . token ( ) . number ( ) . is_integer ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  IntegerStyleValue : : create ( peek_token . token ( ) . number ( ) . integer_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_number_value ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  peek_token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( peek_token . is ( Token : : Type : : Number ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:10:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  NumberStyleValue : : create ( peek_token . token ( ) . number ( ) . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_identifier_value ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-14 16:20:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  value_id  =  value_id_from_string ( component_value . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-10 12:43:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value_id . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  IdentifierStyleValue : : create ( value_id . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Color >  Parser : : parse_rgb_or_hsl_color ( StringView  function_name ,  Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Token  params [ 4 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  legacy_syntax  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  component1  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! component1 . is ( Token : : Type : : Number ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        & &  ! component1 . is ( Token : : Type : : Percentage ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        & &  ! component1 . is ( Token : : Type : : Dimension ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 13:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    params [ 0 ]  =  component1 . token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . peek_token ( ) . is ( Token : : Type : : Comma ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        legacy_syntax  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  component2  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! component2 . is ( Token : : Type : : Number )  & &  ! component2 . is ( Token : : Type : : Percentage ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    params [ 1 ]  =  component2 . token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( legacy_syntax  & &  ! tokens . next_token ( ) . is ( Token : : Type : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 21:20:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  component3  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! component3 . is ( Token : : Type : : Number )  & &  ! component3 . is ( Token : : Type : : Percentage ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    params [ 2 ]  =  component3 . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  alpha_separator  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    bool  has_comma  =  alpha_separator . is ( Token : : Type : : Comma ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    bool  has_slash  =  alpha_separator . is_delim ( ' / ' ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( legacy_syntax  ?  has_comma  :  has_slash )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  component4  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! component4 . is ( Token : : Type : : Number )  & &  ! component4 . is ( Token : : Type : : Percentage ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        params [ 3 ]  =  component4 . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function_name . equals_ignoring_ascii_case ( " rgb " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  function_name . equals_ignoring_ascii_case ( " rgba " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://www.w3.org/TR/css-color-4/#rgb-functions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        u8  a_val  =  255 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( params [ 3 ] . is ( Token : : Type : : Number ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            a_val  =  clamp ( lroundf ( params [ 3 ] . number_value ( )  *  255.0f ) ,  0 ,  255 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( params [ 3 ] . is ( Token : : Type : : Percentage ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            a_val  =  clamp ( lroundf ( params [ 3 ] . percentage ( )  *  2.55f ) ,  0 ,  255 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( params [ 0 ] . is ( Token : : Type : : Number ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  params [ 1 ] . is ( Token : : Type : : Number ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  params [ 2 ] . is ( Token : : Type : : Number ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:51:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            u8  r_val  =  clamp ( llroundf ( params [ 0 ] . number_value ( ) ) ,  0 ,  255 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            u8  g_val  =  clamp ( llroundf ( params [ 1 ] . number_value ( ) ) ,  0 ,  255 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            u8  b_val  =  clamp ( llroundf ( params [ 2 ] . number_value ( ) ) ,  0 ,  255 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Color ( r_val ,  g_val ,  b_val ,  a_val ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 21:20:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( params [ 0 ] . is ( Token : : Type : : Percentage ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  params [ 1 ] . is ( Token : : Type : : Percentage ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  params [ 2 ] . is ( Token : : Type : : Percentage ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 21:20:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            u8  r_val  =  lroundf ( clamp ( params [ 0 ] . percentage ( )  *  2.55f ,  0 ,  255 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            u8  g_val  =  lroundf ( clamp ( params [ 1 ] . percentage ( )  *  2.55f ,  0 ,  255 ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            u8  b_val  =  lroundf ( clamp ( params [ 2 ] . percentage ( )  *  2.55f ,  0 ,  255 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Color ( r_val ,  g_val ,  b_val ,  a_val ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( function_name . equals_ignoring_ascii_case ( " hsl " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  function_name . equals_ignoring_ascii_case ( " hsla " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // https://www.w3.org/TR/css-color-4/#the-hsl-notation
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        float  a_val  =  1.0f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( params [ 3 ] . is ( Token : : Type : : Number ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            a_val  =  params [ 3 ] . number_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( params [ 3 ] . is ( Token : : Type : : Percentage ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            a_val  =  params [ 3 ] . percentage ( )  /  100.0f ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( params [ 0 ] . is ( Token : : Type : : Dimension ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  params [ 1 ] . is ( Token : : Type : : Percentage ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  params [ 2 ] . is ( Token : : Type : : Percentage ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 21:20:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            float  numeric_value  =  params [ 0 ] . dimension_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  unit_string  =  params [ 0 ] . dimension_unit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  angle_type  =  Angle : : unit_from_name ( unit_string ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! angle_type . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 21:20:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  angle  =  Angle  {  numeric_value ,  angle_type . release_value ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            float  h_val  =  fmodf ( angle . to_degrees ( ) ,  360.0f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            float  s_val  =  params [ 1 ] . percentage ( )  /  100.0f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            float  l_val  =  params [ 2 ] . percentage ( )  /  100.0f ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Color : : from_hsla ( h_val ,  s_val ,  l_val ,  a_val ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( params [ 0 ] . is ( Token : : Type : : Number ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  params [ 1 ] . is ( Token : : Type : : Percentage ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            & &  params [ 2 ] . is ( Token : : Type : : Percentage ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            float  h_val  =  fmodf ( params [ 0 ] . number_value ( ) ,  360.0f ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            float  s_val  =  params [ 1 ] . percentage ( )  /  100.0f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            float  l_val  =  params [ 2 ] . percentage ( )  /  100.0f ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Color : : from_hsla ( h_val ,  s_val ,  l_val ,  a_val ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/CSS2/visufx.html#value-def-shape
  
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_rect_value ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! component_value . is_function ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  function  =  component_value . function ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! function . name ( ) . equals_ignoring_ascii_case ( " rect " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Length ,  4 >  params ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 23:31:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    enum  class  CommaRequirement  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Unknown , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        RequiresCommas , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        RequiresNoCommas 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    enum  class  Side  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Top  =  0 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Right  =  1 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Bottom  =  2 , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Left  =  3 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  comma_requirement  =  CommaRequirement : : Unknown ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // In CSS 2.1, the only valid <shape> value is: rect(<top>, <right>, <bottom>, <left>) where
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <top> and <bottom> specify offsets from the top border edge of the box, and <right>, and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //  <left> specify offsets from the left border edge of the box.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 23:31:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( size_t  side  =  0 ;  side  <  4 ;  side + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <top>, <right>, <bottom>, and <left> may either have a <length> value or 'auto'.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Negative lengths are permitted.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  current_token  =  tokens . next_token ( ) . token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( current_token . is ( Token : : Type : : Ident )  & &  current_token . ident ( ) . equals_ignoring_ascii_case ( " auto " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            params . append ( Length : : make_auto ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_length  =  parse_length ( current_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_length . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            params . append ( maybe_length . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 23:31:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // The last side, should be no more tokens following it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( static_cast < Side > ( side )  = =  Side : : Left )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 23:31:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        bool  next_is_comma  =  tokens . peek_token ( ) . is ( Token : : Type : : Comma ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Authors should separate offset values with commas. User agents must support separation
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // with commas, but may also support separation without commas (but not a combination),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // because a previous revision of this specification was ambiguous in this respect.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 23:31:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( comma_requirement  = =  CommaRequirement : : Unknown ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            comma_requirement  =  next_is_comma  ?  CommaRequirement : : RequiresCommas  :  CommaRequirement : : RequiresNoCommas ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( comma_requirement  = =  CommaRequirement : : RequiresCommas )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( next_is_comma ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 23:31:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( comma_requirement  = =  CommaRequirement : : RequiresNoCommas )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( next_is_comma ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 23:31:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 23:31:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  RectStyleValue : : create ( EdgeRect  {  params [ 0 ] ,  params [ 1 ] ,  params [ 2 ] ,  params [ 3 ]  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-31 18:46:35 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Color >  Parser : : parse_color ( ComponentValue  const &  component_value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://www.w3.org/TR/css-color-4/
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  component_value . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  color  =  Color : : from_string ( ident ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( color . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  color ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( component_value . is ( Token : : Type : : Hash ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-04 18:02:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  color  =  Color : : from_string ( DeprecatedString : : formatted ( " #{} " ,  component_value . token ( ) . hash_value ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( color . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  color ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( component_value . is_function ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  function  =  component_value . function ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  values  =  function . values ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-09 19:08:57 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  parse_rgb_or_hsl_color ( function . name ( ) ,  values ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 13:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // https://quirks.spec.whatwg.org/#the-hashless-hex-color-quirk
 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 17:41:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( m_context . in_quirks_mode ( )  & &  property_has_quirk ( m_context . current_property_id ( ) ,  Quirk : : HashlessHexColor ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 13:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // The value of a quirky color is obtained from the possible component values using the following algorithm,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // aborting on the first step that returns a value:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Let cv be the component value.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  cv  =  component_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-04 18:02:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        DeprecatedString  serialization ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 13:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If cv is a <number-token> or a <dimension-token>, follow these substeps:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( cv . is ( Token : : Type : : Number )  | |  cv . is ( Token : : Type : : Dimension ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								            // 1. If cv’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //    This means that values that happen to use scientific notation, e.g., 5e5e5e, will fail to parse.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 21:01:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! cv . token ( ) . number ( ) . is_integer ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 13:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								            // 2. If cv’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  value  =  cv . is ( Token : : Type : : Number )  ?  cv . token ( ) . to_integer ( )  :  cv . token ( ) . dimension_value_int ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( value  <  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								            // 3. Let serialization be the serialization of cv’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            StringBuilder  serialization_builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            serialization_builder . appendff ( " {} " ,  value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // 4. If cv is a <dimension-token>, append the unit to serialization.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( cv . is ( Token : : Type : : Dimension ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                serialization_builder . append ( cv . token ( ) . dimension_unit ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // 5. If serialization consists of fewer than six characters, prepend zeros (U+0030) so that it becomes six characters.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 01:12:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            serialization  =  serialization_builder . to_deprecated_string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 13:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( serialization_builder . length ( )  <  6 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                StringBuilder  builder ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                for  ( size_t  i  =  0 ;  i  <  ( 6  -  serialization_builder . length ( ) ) ;  i + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    builder . append ( ' 0 ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                builder . append ( serialization_builder . string_view ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-06 01:12:49 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                serialization  =  builder . to_deprecated_string ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 13:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								        // 3. Otherwise, cv is an <ident-token>; let serialization be cv’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! cv . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            serialization  =  cv . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 4. If serialization does not consist of three or six characters, return an error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( serialization . length ( )  ! =  3  & &  serialization . length ( )  ! =  6 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 5. If serialization contains any characters not in the range [0-9A-Fa-f] (U+0030 to U+0039, U+0041 to U+0046, U+0061 to U+0066), return an error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  c  :  serialization )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! ( ( c  > =  ' 0 '  & &  c  < =  ' 9 ' )  | |  ( c  > =  ' A '  & &  c  < =  ' F ' )  | |  ( c  > =  ' a '  & &  c  < =  ' f ' ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 6. Return the concatenation of "#" (U+0023) and serialization.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-04 18:02:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        DeprecatedString  concatenation  =  DeprecatedString : : formatted ( " #{} " ,  serialization ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-23 13:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Color : : from_string ( concatenation ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_color_value ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:10:03 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-11-05 17:41:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  color  =  parse_color ( component_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( color . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ColorStyleValue : : create ( color . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-09 21:04:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-10 17:34:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  ident  =  value_id_from_string ( component_value . token ( ) . ident ( ) ) ;  ident . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            switch  ( ident . value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Currentcolor : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebLink : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteActiveLink : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteActiveWindowBorder1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteActiveWindowBorder2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteActiveWindowTitle : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteBase : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteBaseText : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteButton : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteButtonText : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteDesktopBackground : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteFocusOutline : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteHighlightWindowBorder1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteHighlightWindowBorder2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteHighlightWindowTitle : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteHoverHighlight : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteInactiveSelection : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteInactiveSelectionText : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteInactiveWindowBorder1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteInactiveWindowBorder2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteInactiveWindowTitle : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteLink : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteMenuBase : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteMenuBaseText : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteMenuSelection : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteMenuSelectionText : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteMenuStripe : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteMovingWindowBorder1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteMovingWindowBorder2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteMovingWindowTitle : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteRubberBandBorder : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteRubberBandFill : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteRuler : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteRulerActiveText : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteRulerBorder : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteRulerInactiveText : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSelection : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSelectionText : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSyntaxComment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSyntaxControlKeyword : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSyntaxIdentifier : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSyntaxKeyword : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSyntaxNumber : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSyntaxOperator : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSyntaxPreprocessorStatement : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSyntaxPreprocessorValue : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSyntaxPunctuation : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSyntaxString : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteSyntaxType : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteTextCursor : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteThreedHighlight : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteThreedShadow1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteThreedShadow2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteVisitedLink : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteWindow : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : LibwebPaletteWindowText : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  IdentifierStyleValue : : create ( ident . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 15:42:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_ratio_value ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  ratio  =  parse_ratio ( tokens ) ;  ratio . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  RatioStyleValue : : create ( ratio . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_string_value ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2021-07-18 17:12:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-07-14 16:20:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is ( Token : : Type : : String ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  StringStyleValue : : create ( TRY ( String : : from_utf8 ( component_value . token ( ) . string ( ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 21:53:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_image_value ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2021-07-22 13:00:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-11-05 17:41:04 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  url  =  parse_url_function ( component_value ,  AllowedDataUrlType : : Image ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 17:51:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( url . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ImageStyleValue : : create ( url . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  linear_gradient  =  TRY ( parse_linear_gradient_function ( component_value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 19:25:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( linear_gradient ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  linear_gradient ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  conic_gradient  =  TRY ( parse_conic_gradient_function ( component_value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-11 19:12:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( conic_gradient ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  conic_gradient ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  parse_radial_gradient_function ( component_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-22 13:00:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 16:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://svgwg.org/svg2-draft/painting.html#SpecifyingPaint
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_paint_value ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `<paint> = none | <color> | <url> [none | <color>]? | context-fill | context-stroke`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-16 14:12:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  color  =  TRY ( parse_color_value ( tokens . peek_token ( ) ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  color ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  url  =  TRY ( parse_url_value ( tokens . peek_token ( ) ,  AllowedDataUrlType : : Image ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Accept `[none | <color>]?`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  url ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: <color> also accepts identifiers, so we do this identifier check last.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 16:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . peek_token ( ) . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_ident  =  value_id_from_string ( tokens . peek_token ( ) . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( maybe_ident . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: Accept `context-fill` and `context-stroke`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            switch  ( * maybe_ident )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  IdentifierStyleValue : : create ( * maybe_ident ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								template < typename  ParseFunction >  
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_comma_separated_value_list ( Vector < ComponentValue >  const &  component_values ,  ParseFunction  parse_one_value )  
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  first  =  TRY ( parse_one_value ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! first  | |  ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  first ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 00:41:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  values ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    values . append ( first . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! tokens . next_token ( ) . is ( Token : : Type : : Comma ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_value  =  TRY ( parse_one_value ( tokens ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            values . append ( maybe_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  StyleValueList : : create ( move ( values ) ,  StyleValueList : : Separator : : Comma ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:31:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_simple_comma_separated_value_list ( PropertyID  property_id ,  Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  parse_comma_separated_value_list ( component_values ,  [ = ,  this ] ( auto &  tokens )  - >  ErrorOr < RefPtr < StyleValue > >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:31:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  value  =  TRY ( parse_css_value_for_property ( property_id ,  tokens ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  void  remove_property ( Vector < PropertyID > &  properties ,  PropertyID  property_to_remove )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    properties . remove_first_matching ( [ & ] ( auto  it )  {  return  it  = =  property_to_remove ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-08 15:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-sizing-4/#aspect-ratio
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_aspect_ratio_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // `auto || <ratio>`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  auto_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  ratio_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_value  =  TRY ( parse_css_value_for_property ( PropertyID : : AspectRatio ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( maybe_value - > is_ratio ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ratio_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ratio_value  =  maybe_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( maybe_value - > is_identifier ( )  & &  maybe_value - > as_identifier ( ) . id ( )  = =  ValueID : : Auto )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto_value  =  maybe_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto_value  & &  ratio_value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  TRY ( StyleValueList : : create ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            StyleValueVector  {  auto_value . release_nonnull ( ) ,  ratio_value . release_nonnull ( )  } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            StyleValueList : : Separator : : Space ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ratio_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ratio_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  auto_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_background_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-08-10 16:20:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-02-20 00:41:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  background_images ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  background_positions ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  background_sizes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  background_repeats ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  background_attachments ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  background_clips ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  background_origins ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  background_color ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 13:03:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  initial_background_image  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : BackgroundImage ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  initial_background_position  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : BackgroundPosition ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  initial_background_size  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : BackgroundSize ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  initial_background_repeat  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : BackgroundRepeat ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  initial_background_attachment  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : BackgroundAttachment ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  initial_background_clip  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : BackgroundClip ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  initial_background_origin  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : BackgroundOrigin ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  initial_background_color  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : BackgroundColor ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Per-layer values
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  background_image ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 16:30:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  background_position ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 16:15:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  background_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  background_repeat ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 17:46:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  background_attachment ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 20:28:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  background_clip ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  background_origin ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    bool  has_multiple_layers  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // BackgroundSize is always parsed as part of BackgroundPosition, so we don't include it here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < PropertyID >  remaining_layer_properties  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        PropertyID : : BackgroundAttachment , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        PropertyID : : BackgroundClip , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        PropertyID : : BackgroundColor , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        PropertyID : : BackgroundImage , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        PropertyID : : BackgroundOrigin , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        PropertyID : : BackgroundPosition , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        PropertyID : : BackgroundRepeat , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  background_layer_is_valid  =  [ & ] ( bool  allow_background_color )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( allow_background_color )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( background_color ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( background_color ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  background_image  | |  background_position  | |  background_size  | |  background_repeat  | |  background_attachment  | |  background_clip  | |  background_origin ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  complete_background_layer  =  [ & ] ( )  - >  ErrorOr < void >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 13:03:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( background_images . try_append ( background_image  ?  background_image . release_nonnull ( )  :  initial_background_image ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( background_positions . try_append ( background_position  ?  background_position . release_nonnull ( )  :  initial_background_position ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( background_sizes . try_append ( background_size  ?  background_size . release_nonnull ( )  :  initial_background_size ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( background_repeats . try_append ( background_repeat  ?  background_repeat . release_nonnull ( )  :  initial_background_repeat ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( background_attachments . try_append ( background_attachment  ?  background_attachment . release_nonnull ( )  :  initial_background_attachment ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! background_origin  & &  ! background_clip )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 13:03:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            background_origin  =  initial_background_origin ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            background_clip  =  initial_background_clip ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( ! background_clip )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            background_clip  =  background_origin ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( background_origins . try_append ( background_origin . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( background_clips . try_append ( background_clip . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_image  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_position  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_size  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_repeat  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_attachment  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_clip  =  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_origin  =  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        remaining_layer_properties . clear_with_capacity ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remaining_layer_properties . unchecked_append ( PropertyID : : BackgroundAttachment ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remaining_layer_properties . unchecked_append ( PropertyID : : BackgroundClip ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remaining_layer_properties . unchecked_append ( PropertyID : : BackgroundColor ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remaining_layer_properties . unchecked_append ( PropertyID : : BackgroundImage ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remaining_layer_properties . unchecked_append ( PropertyID : : BackgroundOrigin ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remaining_layer_properties . unchecked_append ( PropertyID : : BackgroundPosition ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remaining_layer_properties . unchecked_append ( PropertyID : : BackgroundRepeat ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 16:30:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( tokens . peek_token ( ) . is ( Token : : Type : : Comma ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            has_multiple_layers  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! background_layer_is_valid ( false ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( complete_background_layer ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  value_and_property  =  TRY ( parse_css_value_for_properties ( remaining_layer_properties ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value_and_property . style_value ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  value  =  value_and_property . style_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remove_property ( remaining_layer_properties ,  value_and_property . property ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( value_and_property . property )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : BackgroundAttachment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! background_attachment ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 17:46:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            background_attachment  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : BackgroundColor : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! background_color ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            background_color  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : BackgroundImage : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! background_image ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            background_image  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : BackgroundClip : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : BackgroundOrigin :  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 20:28:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // background-origin and background-clip accept the same values. From the spec:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //   "If one <box> value is present then it sets both background-origin and background-clip to that value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //    If two values are present, then the first sets background-origin and the second background-clip."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //        - https://www.w3.org/TR/css-backgrounds-3/#background
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // So, we put the first one in background-origin, then if we get a second, we put it in background-clip.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // If we only get one, we copy the value before creating the BackgroundStyleValue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! background_origin )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                background_origin  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( ! background_clip )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 20:28:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                background_clip  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 20:28:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 20:28:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : BackgroundPosition :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! background_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 16:30:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  maybe_background_position  =  TRY ( parse_single_background_position_value ( tokens ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 16:30:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                background_position  =  maybe_background_position . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 16:15:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // Attempt to parse `/ <background-size>`
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 16:15:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  maybe_slash  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( maybe_slash . is_delim ( ' / ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( auto  maybe_background_size  =  TRY ( parse_single_background_size_value ( tokens ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 16:15:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        background_size  =  maybe_background_size . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 16:30:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : BackgroundRepeat :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! background_repeat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  maybe_repeat  =  TRY ( parse_single_background_repeat_value ( tokens ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                background_repeat  =  maybe_repeat . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:50:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! background_layer_is_valid ( true ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // We only need to create StyleValueLists if there are multiple layers.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Otherwise, we can pass the single StyleValues directly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( has_multiple_layers )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( complete_background_layer ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! background_color ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 13:03:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            background_color  =  initial_background_color ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  BackgroundStyleValue : : create ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            background_color . release_nonnull ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( StyleValueList : : create ( move ( background_images ) ,  StyleValueList : : Separator : : Comma ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( StyleValueList : : create ( move ( background_positions ) ,  StyleValueList : : Separator : : Comma ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( StyleValueList : : create ( move ( background_sizes ) ,  StyleValueList : : Separator : : Comma ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( StyleValueList : : create ( move ( background_repeats ) ,  StyleValueList : : Separator : : Comma ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( StyleValueList : : create ( move ( background_attachments ) ,  StyleValueList : : Separator : : Comma ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( StyleValueList : : create ( move ( background_origins ) ,  StyleValueList : : Separator : : Comma ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( StyleValueList : : create ( move ( background_clips ) ,  StyleValueList : : Separator : : Comma ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 11:12:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! background_color ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 13:03:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        background_color  =  initial_background_color ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! background_image ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 13:03:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        background_image  =  initial_background_image ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 16:30:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! background_position ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 13:03:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        background_position  =  initial_background_position ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 16:15:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! background_size ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 13:03:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        background_size  =  initial_background_size ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! background_repeat ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 13:03:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        background_repeat  =  initial_background_repeat ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 17:46:45 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! background_attachment ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 13:03:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        background_attachment  =  initial_background_attachment ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 20:28:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! background_origin  & &  ! background_clip )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 13:03:56 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        background_origin  =  initial_background_origin ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_clip  =  initial_background_clip ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 20:28:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( ! background_clip )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_clip  =  background_origin ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  BackgroundStyleValue : : create ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_color . release_nonnull ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_image . release_nonnull ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_position . release_nonnull ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 16:15:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        background_size . release_nonnull ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        background_repeat . release_nonnull ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-03 20:28:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        background_attachment . release_nonnull ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        background_origin . release_nonnull ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        background_clip . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  Optional < PositionEdge >  identifier_to_edge ( ValueID  identifier )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : Top : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  PositionEdge : : Top ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : Bottom : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  PositionEdge : : Bottom ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : Left : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  PositionEdge : : Left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : Right : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  PositionEdge : : Right ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-07 22:48:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  Optional < LengthPercentage >  style_value_to_length_percentage ( auto  value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value - > is_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  LengthPercentage  {  value - > as_percentage ( ) . percentage ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 12:28:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value - > is_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  LengthPercentage  {  value - > as_length ( ) . length ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value - > is_calculated ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  LengthPercentage  {  value - > as_calculated ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-07 22:48:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_single_background_position_value ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: This *looks* like it parses a <position>, but it doesn't. From the spec:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //      "Note: The background-position property also accepts a three-value syntax.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //       This has been disallowed generically because it creates parsing ambiguities
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //       when combined with other length or percentage components in a property value."
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //           - https://www.w3.org/TR/css-values-4/#typedef-position
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //       So, we'll need a separate function to parse <position> later.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_horizontal  =  [ ] ( ValueID  identifier )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Left : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Right : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_vertical  =  [ ] ( ValueID  identifier )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Top : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Bottom : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    struct  EdgeOffset  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        PositionEdge  edge ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-19 11:20:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        LengthPercentage  offset ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        bool  edge_provided ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        bool  offset_provided ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < EdgeOffset >  horizontal ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < EdgeOffset >  vertical ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  found_center  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-12-11 11:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const  center_offset  =  Percentage  {  50  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const  zero_offset  =  Length : : make_px ( 0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Check if we're done
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  seen_items  =  ( horizontal . has_value ( )  ?  1  :  0 )  +  ( vertical . has_value ( )  ?  1  :  0 )  +  ( found_center  ?  1  :  0 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( seen_items  = =  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 15:46:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_value  =  TRY ( parse_css_value_for_property ( PropertyID : : BackgroundPosition ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_value ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  value  =  maybe_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 15:46:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  offset  =  style_value_to_length_percentage ( value ) ;  offset . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-19 11:20:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! horizontal . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-11 11:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                horizontal  =  EdgeOffset  {  PositionEdge : : Left ,  * offset ,  false ,  true  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-19 11:20:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( ! vertical . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-11 11:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                vertical  =  EdgeOffset  {  PositionEdge : : Top ,  * offset ,  false ,  true  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-19 11:20:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-19 11:20:40 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  try_parse_offset  =  [ & ] ( bool &  offset_provided )  - >  ErrorOr < LengthPercentage >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 15:46:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-11 11:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 15:46:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  maybe_value  =  TRY ( parse_css_value_for_property ( PropertyID : : BackgroundPosition ,  tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-11 11:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! maybe_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  zero_offset ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  offset  =  style_value_to_length_percentage ( maybe_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-11 11:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( offset . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    offset_provided  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 15:46:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-11 11:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  * offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-11 11:51:00 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  zero_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-19 12:00:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value - > is_identifier ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  identifier  =  value - > to_identifier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is_horizontal ( identifier ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                bool  offset_provided  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  offset  =  TRY ( try_parse_offset ( offset_provided ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                horizontal  =  EdgeOffset  {  * identifier_to_edge ( identifier ) ,  offset ,  true ,  offset_provided  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( is_vertical ( identifier ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                bool  offset_provided  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  offset  =  TRY ( try_parse_offset ( offset_provided ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                vertical  =  EdgeOffset  {  * identifier_to_edge ( identifier ) ,  offset ,  true ,  offset_provided  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( identifier  = =  ValueID : : Center )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                found_center  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( found_center )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( horizontal . has_value ( )  & &  vertical . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! horizontal . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            horizontal  =  EdgeOffset  {  PositionEdge : : Left ,  center_offset ,  true ,  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! vertical . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            vertical  =  EdgeOffset  {  PositionEdge : : Top ,  center_offset ,  true ,  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! horizontal . has_value ( )  & &  ! vertical . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Unpack `<edge> <length>`:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The loop above reads this pattern as a single EdgeOffset, when actually, it should be treated
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // as `x y` if the edge is horizontal, and `y` (with the second token reconsumed) otherwise.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! vertical . has_value ( )  & &  horizontal - > edge_provided  & &  horizontal - > offset_provided )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Split into `x y`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        vertical  =  EdgeOffset  {  PositionEdge : : Top ,  horizontal - > offset ,  false ,  true  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        horizontal - > offset  =  zero_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        horizontal - > offset_provided  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( ! horizontal . has_value ( )  & &  vertical - > edge_provided  & &  vertical - > offset_provided )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // `y`, reconsume
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        vertical - > offset  =  zero_offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        vertical - > offset_provided  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // If only one value is specified, the second value is assumed to be center.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! horizontal . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        horizontal  =  EdgeOffset  {  PositionEdge : : Left ,  center_offset ,  false ,  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! vertical . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        vertical  =  EdgeOffset  {  PositionEdge : : Top ,  center_offset ,  false ,  false  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  PositionStyleValue : : create ( 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( EdgeStyleValue : : create ( horizontal - > edge ,  horizontal - > offset ) ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( EdgeStyleValue : : create ( vertical - > edge ,  vertical - > offset ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_single_background_position_x_or_y_value ( TokenStream < ComponentValue > &  tokens ,  PropertyID  property )  
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    PositionEdge  relative_edge  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( property  = =  PropertyID : : BackgroundPositionX )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // [ center | [ [ left | right | x-start | x-end ]? <length-percentage>? ]! ]#
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        relative_edge  =  PositionEdge : : Left ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( property  = =  PropertyID : : BackgroundPositionY )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // [ center | [ [ top | bottom | y-start | y-end ]? <length-percentage>? ]! ]#
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        relative_edge  =  PositionEdge : : Top ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 15:46:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  value  =  TRY ( parse_css_value_for_property ( property ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-19 12:00:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( value - > is_identifier ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  identifier  =  value - > to_identifier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( identifier  = =  ValueID : : Center )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  EdgeStyleValue : : create ( relative_edge ,  Percentage  {  50  } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  edge  =  identifier_to_edge ( identifier ) ;  edge . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            relative_edge  =  * edge ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 15:46:49 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            value  =  TRY ( parse_css_value_for_property ( property ,  tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  EdgeStyleValue : : create ( relative_edge ,  Length : : make_px ( 0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  offset  =  style_value_to_length_percentage ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( offset . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  EdgeStyleValue : : create ( relative_edge ,  * offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_single_background_repeat_value ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-08-10 10:21:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 10:21:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_directional_repeat  =  [ ] ( StyleValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  value_id  =  value . to_identifier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  value_id  = =  ValueID : : RepeatX  | |  value_id  = =  ValueID : : RepeatY ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-03 20:10:18 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  as_repeat  =  [ ] ( ValueID  identifier )  - >  Optional < Repeat >  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 17:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : NoRepeat : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Repeat : : NoRepeat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Repeat : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Repeat : : Repeat ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Round : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Repeat : : Round ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Space : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Repeat : : Space ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-03 20:10:18 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 17:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 15:43:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_x_value  =  TRY ( parse_css_value_for_property ( PropertyID : : BackgroundRepeat ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_x_value ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  x_value  =  maybe_x_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 10:21:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_directional_repeat ( * x_value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  value_id  =  x_value - > to_identifier ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  BackgroundRepeatStyleValue : : create ( 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 17:38:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            value_id  = =  ValueID : : RepeatX  ?  Repeat : : Repeat  :  Repeat : : NoRepeat , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            value_id  = =  ValueID : : RepeatX  ?  Repeat : : NoRepeat  :  Repeat : : Repeat ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 10:21:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-03 20:10:18 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  x_repeat  =  as_repeat ( x_value - > to_identifier ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! x_repeat . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // See if we have a second value for Y
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 15:43:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_y_value  =  TRY ( parse_css_value_for_property ( PropertyID : : BackgroundRepeat ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_y_value )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // We don't have a second value, so use x for both
 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  BackgroundRepeatStyleValue : : create ( x_repeat . value ( ) ,  x_repeat . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 10:21:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  y_value  =  maybe_y_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_directional_repeat ( * y_value ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-03 20:10:18 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  y_repeat  =  as_repeat ( y_value - > to_identifier ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! y_repeat . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  BackgroundRepeatStyleValue : : create ( x_repeat . value ( ) ,  y_repeat . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-04 15:56:10 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-08-10 10:21:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_single_background_size_value ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-11-05 13:44:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 13:44:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-16 20:24:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  get_length_percentage  =  [ ] ( StyleValue &  style_value )  - >  Optional < LengthPercentage >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-17 19:53:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( style_value . has_auto ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  LengthPercentage  {  Length : : make_auto ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-16 20:24:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( style_value . is_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  LengthPercentage  {  style_value . as_percentage ( ) . percentage ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 12:28:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( style_value . is_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  LengthPercentage  {  style_value . as_length ( ) . length ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-16 20:24:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 15:49:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_x_value  =  TRY ( parse_css_value_for_property ( PropertyID : : BackgroundSize ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_x_value ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 13:44:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  x_value  =  maybe_x_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-06-25 16:54:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( x_value - > to_identifier ( )  = =  ValueID : : Cover  | |  x_value - > to_identifier ( )  = =  ValueID : : Contain )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 13:44:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  x_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-06-25 16:54:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 13:44:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 15:49:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_y_value  =  TRY ( parse_css_value_for_property ( PropertyID : : BackgroundSize ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_y_value )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-14 10:42:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  y_value  =  LengthPercentage  {  Length : : make_auto ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-16 20:24:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  x_size  =  get_length_percentage ( * x_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! x_size . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-14 10:42:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  BackgroundSizeStyleValue : : create ( x_size . value ( ) ,  y_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-16 20:24:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 13:44:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  y_value  =  maybe_y_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-16 20:24:35 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  x_size  =  get_length_percentage ( * x_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  y_size  =  get_length_percentage ( * y_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 13:44:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! x_size . has_value ( )  | |  ! y_size . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 13:44:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  BackgroundSizeStyleValue : : create ( x_size . release_value ( ) ,  y_size . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 13:44:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_border_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  >  3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  border_width ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  border_color ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  border_style ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  remaining_longhands  =  Vector  {  PropertyID : : BorderWidth ,  PropertyID : : BorderColor ,  PropertyID : : BorderStyle  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  property_and_value  =  TRY ( parse_css_value_for_properties ( remaining_longhands ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! property_and_value . style_value ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  value  =  property_and_value . style_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remove_property ( remaining_longhands ,  property_and_value . property ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( property_and_value . property )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : BorderWidth :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! border_width ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            border_width  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : BorderColor :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! border_color ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            border_color  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : BorderStyle :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! border_style ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            border_style  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:41:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! border_width ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        border_width  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : BorderWidth ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! border_style ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        border_style  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : BorderStyle ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! border_color ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        border_color  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : BorderColor ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  BorderStyleValue : : create ( border_width . release_nonnull ( ) ,  border_style . release_nonnull ( ) ,  border_color . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_border_radius_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 20:49:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  horizontal  =  parse_dimension ( component_values [ 0 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  vertical  =  parse_dimension ( component_values [ 1 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( horizontal . has_value ( )  & &  horizontal - > is_length_percentage ( )  & &  vertical . has_value ( )  & &  vertical - > is_length_percentage ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  BorderRadiusStyleValue : : create ( horizontal - > length_percentage ( ) ,  vertical - > length_percentage ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 20:49:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  radius  =  parse_dimension ( component_values [ 0 ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( radius . has_value ( )  & &  radius - > is_length_percentage ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  BorderRadiusStyleValue : : create ( radius - > length_percentage ( ) ,  radius - > length_percentage ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_border_radius_shorthand_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:05:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  top_left  =  [ & ] ( Vector < LengthPercentage > &  radii )  {  return  radii [ 0 ] ;  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  top_right  =  [ & ] ( Vector < LengthPercentage > &  radii )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( radii . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  4 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  3 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  radii [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  radii [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:05:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  bottom_right  =  [ & ] ( Vector < LengthPercentage > &  radii )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( radii . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  4 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  3 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  radii [ 2 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  radii [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:05:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  bottom_left  =  [ & ] ( Vector < LengthPercentage > &  radii )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( radii . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  4 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  radii [ 3 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  3 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  radii [ 1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  1 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  radii [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:05:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < LengthPercentage >  horizontal_radii ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < LengthPercentage >  vertical_radii ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    bool  reading_vertical  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  value  :  component_values )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value . is_delim ( ' / ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( reading_vertical  | |  horizontal_radii . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            reading_vertical  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:05:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_dimension  =  parse_dimension ( value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_dimension . has_value ( )  | |  ! maybe_dimension - > is_length_percentage ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( reading_vertical )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:05:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            vertical_radii . append ( maybe_dimension - > length_percentage ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-07 17:05:15 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            horizontal_radii . append ( maybe_dimension - > length_percentage ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( horizontal_radii . size ( )  >  4  | |  vertical_radii . size ( )  >  4 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  horizontal_radii . is_empty ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  ( reading_vertical  & &  vertical_radii . is_empty ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  top_left_radius  =  TRY ( BorderRadiusStyleValue : : create ( top_left ( horizontal_radii ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        vertical_radii . is_empty ( )  ?  top_left ( horizontal_radii )  :  top_left ( vertical_radii ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  top_right_radius  =  TRY ( BorderRadiusStyleValue : : create ( top_right ( horizontal_radii ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        vertical_radii . is_empty ( )  ?  top_right ( horizontal_radii )  :  top_right ( vertical_radii ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  bottom_right_radius  =  TRY ( BorderRadiusStyleValue : : create ( bottom_right ( horizontal_radii ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        vertical_radii . is_empty ( )  ?  bottom_right ( horizontal_radii )  :  bottom_right ( vertical_radii ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  bottom_left_radius  =  TRY ( BorderRadiusStyleValue : : create ( bottom_left ( horizontal_radii ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        vertical_radii . is_empty ( )  ?  bottom_left ( horizontal_radii )  :  bottom_left ( vertical_radii ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-18 17:10:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  BorderRadiusShorthandStyleValue : : create ( move ( top_left_radius ) ,  move ( top_right_radius ) ,  move ( bottom_right_radius ) ,  move ( bottom_left_radius ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_shadow_value ( Vector < ComponentValue >  const &  component_values ,  AllowInsetKeyword  allow_inset_keyword )  
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:12:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2021-10-15 19:25:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // "none"
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  1  & &  component_values . first ( ) . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  TRY ( parse_identifier_value ( component_values . first ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-15 19:25:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident  & &  ident - > to_identifier ( )  = =  ValueID : : None ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  ident ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 16:59:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  parse_comma_separated_value_list ( component_values ,  [ this ,  allow_inset_keyword ] ( auto &  tokens )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  parse_single_shadow_value ( tokens ,  allow_inset_keyword ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_single_shadow_value ( TokenStream < ComponentValue > &  tokens ,  AllowInsetKeyword  allow_inset_keyword )  
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < Color >  color ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  offset_x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  offset_y ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  blur_radius ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  spread_distance ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 16:55:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < ShadowPlacement >  placement ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  possibly_dynamic_length  =  [ & ] ( ComponentValue  const &  token )  - >  ErrorOr < RefPtr < StyleValue > >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_dynamic_value  =  TRY ( parse_dynamic_value ( token ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_dynamic_value - > is_calculated ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  calculated_value  =  maybe_dynamic_value - > as_calculated ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! calculated_value . resolves_to_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  calculated_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_length  =  parse_length ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_length . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  LengthStyleValue : : create ( maybe_length . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_color  =  parse_color ( token ) ;  maybe_color . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( color . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            color  =  maybe_color . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:12:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_offset_x  =  TRY ( possibly_dynamic_length ( token ) ) ;  maybe_offset_x )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // horizontal offset
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( offset_x ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            offset_x  =  maybe_offset_x ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:12:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // vertical offset
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_offset_y  =  TRY ( possibly_dynamic_length ( tokens . peek_token ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_offset_y ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            offset_y  =  maybe_offset_y ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:12:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // blur radius (optional)
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_blur_radius  =  TRY ( possibly_dynamic_length ( tokens . peek_token ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_blur_radius ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            blur_radius  =  maybe_blur_radius ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:12:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:47:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // spread distance (optional)
 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:47:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_spread_distance  =  TRY ( possibly_dynamic_length ( tokens . peek_token ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_spread_distance ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:47:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            spread_distance  =  maybe_spread_distance ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:47:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 16:59:44 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( allow_inset_keyword  = =  AllowInsetKeyword : : Yes 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            & &  token . is ( Token : : Type : : Ident )  & &  token . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " inset " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:47:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( placement . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 16:55:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            placement  =  ShadowPlacement : : Inner ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:12:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 14:07:06 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:12:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: If color is absent, default to `currentColor`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! color . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        color  =  Color : : NamedColor : : Black ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // x/y offsets are required
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! offset_x  | |  ! offset_y ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Other lengths default to 0
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! blur_radius ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        blur_radius  =  TRY ( LengthStyleValue : : create ( Length : : make_px ( 0 ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! spread_distance ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        spread_distance  =  TRY ( LengthStyleValue : : create ( Length : : make_px ( 0 ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 13:47:11 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Placement is outer by default
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! placement . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 16:55:22 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        placement  =  ShadowPlacement : : Outer ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-08 12:41:50 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 17:08:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-31 16:07:06 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  ShadowStyleValue : : create ( color . release_value ( ) ,  offset_x . release_nonnull ( ) ,  offset_y . release_nonnull ( ) ,  blur_radius . release_nonnull ( ) ,  spread_distance . release_nonnull ( ) ,  placement . release_value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:12:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_content_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: `content` accepts several kinds of function() type, which we don't handle in property_accepts_value() yet.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_single_value_identifier  =  [ ] ( ValueID  identifier )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Normal : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  identifier  =  TRY ( parse_identifier_value ( component_values . first ( ) ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is_single_value_identifier ( identifier - > to_identifier ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  identifier ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 00:41:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  content_values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  alt_text_values ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    bool  in_alt_text  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  next  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( next . is_delim ( ' / ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( in_alt_text  | |  content_values . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            in_alt_text  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  style_value  =  TRY ( parse_css_value_for_property ( PropertyID : : Content ,  tokens ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is_single_value_identifier ( style_value - > to_identifier ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( in_alt_text )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                TRY ( alt_text_values . try_append ( style_value . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:47:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                TRY ( content_values . try_append ( style_value . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( content_values . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( in_alt_text  & &  alt_text_values . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValueList >  alt_text ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! alt_text_values . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        alt_text  =  TRY ( StyleValueList : : create ( move ( alt_text_values ) ,  StyleValueList : : Separator : : Space ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  ContentStyleValue : : create ( TRY ( StyleValueList : : create ( move ( content_values ) ,  StyleValueList : : Separator : : Space ) ) ,  move ( alt_text ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-display-3/#the-display-properties
  
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_display_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_inside  =  [ ] ( ValueID  identifier )  - >  Optional < Display : : Inside >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Flow : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Display : : Inside : : Flow ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : FlowRoot : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Display : : Inside : : FlowRoot ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Table : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Display : : Inside : : Table ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Flex : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Display : : Inside : : Flex ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Grid : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Display : : Inside : : Grid ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Ruby : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Display : : Inside : : Ruby ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_outside  =  [ ] ( ValueID  identifier )  - >  Optional < Display : : Outside >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Block : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Display : : Outside : : Block ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : Inline : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Display : : Outside : : Inline ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  ValueID : : RunIn : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  Display : : Outside : : RunIn ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_single_component_display  =  [ & ] ( Vector < ComponentValue >  const &  component_values )  - >  ErrorOr < Optional < Display > >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  identifier  =  TRY ( parse_identifier_value ( component_values . first ( ) ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            switch  ( identifier - > to_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // display-outside
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Block : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : Block ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Inline : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : Inline ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : RunIn : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : RunIn ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // display-inside
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Flow : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : Flow ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : FlowRoot : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : FlowRoot ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Table : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : Table ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Flex : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : Flex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Grid : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : Grid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Ruby : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : Ruby ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // display-listitem
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : ListItem : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : ListItem ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // display-internal
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : TableRowGroup : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : TableRowGroup  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : TableHeaderGroup : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : TableHeaderGroup  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : TableFooterGroup : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : TableFooterGroup  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : TableRow : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : TableRow  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : TableCell : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : TableCell  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : TableColumnGroup : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : TableColumnGroup  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : TableColumn : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : TableColumn  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : TableCaption : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : TableCaption  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : RubyBase : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : RubyBase  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : RubyText : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : RubyText  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : RubyBaseContainer : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : RubyBaseContainer  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : RubyTextContainer : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display  {  Display : : Internal : : RubyTextContainer  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // display-box
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Contents : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // FIXME this should be Display::Short::Contents but contents is currently not implemented
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : Flow ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : None ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // display-legacy
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : InlineBlock : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : InlineBlock ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : InlineTable : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : InlineTable ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : InlineFlex : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : InlineFlex ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : InlineGrid : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Display : : from_short ( Display : : Short : : InlineGrid ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            default : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  OptionalNone  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  OptionalNone  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_multi_component_display  =  [ & ] ( Vector < ComponentValue >  const &  component_values )  - >  ErrorOr < Optional < Display > >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  list_item  =  Display : : ListItem : : No ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Display : : Inside  inside  =  Display : : Inside : : Flow ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Display : : Outside  outside  =  Display : : Outside : : Block ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( size_t  i  =  0 ;  i  <  component_values . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  value  =  TRY ( parse_identifier_value ( component_values [ i ] ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  identifier  =  value - > to_identifier ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ValueID : : ListItem  = =  identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    list_item  =  Display : : ListItem : : Yes ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  inside_value  =  parse_inside ( identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( inside_value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    inside  =  inside_value . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  outside_value  =  parse_outside ( identifier ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( outside_value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    outside  =  outside_value . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The spec does not allow any other inside values to be combined with list-item
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <display-outside>? && [ flow | flow-root ]? && list-item
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( list_item  = =  Display : : ListItem : : Yes  & &  inside  ! =  Display : : Inside : : Flow  & &  inside  ! =  Display : : Inside : : FlowRoot ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  OptionalNone  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Display  {  outside ,  inside ,  list_item  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < Display >  display ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        display  =  TRY ( parse_single_component_display ( component_values ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        display  =  TRY ( parse_multi_component_display ( component_values ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( display . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  DisplayStyleValue : : create ( display . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_filter_value_list_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  1  & &  component_values . first ( ) . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  TRY ( parse_identifier_value ( component_values . first ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident  & &  ident - > to_identifier ( )  = =  ValueID : : None ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  ident ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  tokens  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: <url>s are ignored for now
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <filter-value-list> = [ <filter-function> | <url> ]+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    enum  class  FilterToken  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Color filters:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Brightness , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Contrast , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Grayscale , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Invert , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Opacity , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Saturate , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Sepia , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Special filters:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Blur , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        DropShadow , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        HueRotate 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  filter_token_to_operation  =  [ & ] ( auto  filter )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY ( to_underlying ( filter )  <  to_underlying ( FilterToken : : Blur ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  static_cast < Filter : : Color : : Operation > ( filter ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_number_percentage  =  [ & ] ( auto &  token )  - >  Optional < NumberPercentage >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Percentage ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  NumberPercentage ( Percentage ( token . token ( ) . percentage ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Number ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  NumberPercentage ( Number ( Number : : Type : : Number ,  token . token ( ) . number_value ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_filter_function_name  =  [ & ] ( auto  name )  - >  Optional < FilterToken >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name . equals_ignoring_ascii_case ( " blur " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FilterToken : : Blur ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name . equals_ignoring_ascii_case ( " brightness " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FilterToken : : Brightness ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name . equals_ignoring_ascii_case ( " contrast " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FilterToken : : Contrast ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name . equals_ignoring_ascii_case ( " drop-shadow " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FilterToken : : DropShadow ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name . equals_ignoring_ascii_case ( " grayscale " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FilterToken : : Grayscale ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name . equals_ignoring_ascii_case ( " hue-rotate " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FilterToken : : HueRotate ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name . equals_ignoring_ascii_case ( " invert " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FilterToken : : Invert ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name . equals_ignoring_ascii_case ( " opacity " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FilterToken : : Opacity ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name . equals_ignoring_ascii_case ( " saturate " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FilterToken : : Saturate ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name . equals_ignoring_ascii_case ( " sepia " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FilterToken : : Sepia ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_filter_function  =  [ & ] ( auto  filter_token ,  auto  function_values )  - >  Optional < FilterFunction >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TokenStream  tokens  {  function_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  if_no_more_tokens_return  =  [ & ] ( auto  filter )  - >  Optional < FilterFunction >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  filter ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( filter_token  = =  FilterToken : : Blur )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // blur( <length>? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Filter : : Blur  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  blur_radius  =  parse_length ( tokens . next_token ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! blur_radius . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  if_no_more_tokens_return ( Filter : : Blur  {  * blur_radius  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( filter_token  = =  FilterToken : : DropShadow )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-07 22:44:33 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  next_token  =  [ & ] ( )  - >  auto &  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  token ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // drop-shadow( [ <color>? && <length>{2,3} ] )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Note: The following code is a little awkward to allow the color to be before or after the lengths.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  first_param  =  next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            Optional < Length >  maybe_radius  =  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_color  =  parse_color ( first_param ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  x_offset  =  parse_length ( maybe_color . has_value ( )  ?  next_token ( )  :  first_param ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! x_offset . has_value ( )  | |  ! tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  y_offset  =  parse_length ( next_token ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! y_offset . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto &  token  =  next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                maybe_radius  =  parse_length ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! maybe_color . has_value ( )  & &  ( ! maybe_radius . has_value ( )  | |  tokens . has_next_token ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    maybe_color  =  parse_color ( ! maybe_radius . has_value ( )  ?  token  :  next_token ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! maybe_color . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  if  ( ! maybe_radius . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  if_no_more_tokens_return ( Filter : : DropShadow  {  * x_offset ,  * y_offset ,  maybe_radius ,  maybe_color  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( filter_token  = =  FilterToken : : HueRotate )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // hue-rotate( [ <angle> | <zero> ]? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Filter : : HueRotate  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( token . is ( Token : : Type : : Number ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // hue-rotate(0)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  number  =  token . token ( ) . number ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( number . is_integer ( )  & &  number . integer_value ( )  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  if_no_more_tokens_return ( Filter : : HueRotate  {  Filter : : HueRotate : : Zero  { }  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! token . is ( Token : : Type : : Dimension ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            float  angle_value  =  token . token ( ) . dimension_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  angle_unit_name  =  token . token ( ) . dimension_unit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  angle_unit  =  Angle : : unit_from_name ( angle_unit_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! angle_unit . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            Angle  angle  {  angle_value ,  angle_unit . release_value ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  if_no_more_tokens_return ( Filter : : HueRotate  {  angle  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Simple filters:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // brightness( <number-percentage>? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // contrast( <number-percentage>? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // grayscale( <number-percentage>? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // invert( <number-percentage>? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // opacity( <number-percentage>? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // sepia( <number-percentage>? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // saturate( <number-percentage>? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Filter : : Color  {  filter_token_to_operation ( filter_token )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  amount  =  parse_number_percentage ( tokens . next_token ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! amount . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  if_no_more_tokens_return ( Filter : : Color  {  filter_token_to_operation ( filter_token ) ,  * amount  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < FilterFunction >  filter_value_list  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! token . is_function ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  filter_token  =  parse_filter_function_name ( token . function ( ) . name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! filter_token . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  filter_function  =  parse_filter_function ( * filter_token ,  token . function ( ) . values ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! filter_function . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        filter_value_list . append ( * filter_function ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( filter_value_list . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  FilterValueListStyleValue : : create ( move ( filter_value_list ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_flex_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-19 10:08:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // One-value syntax: <flex-grow> | <flex-basis> | none
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  properties  =  Array  {  PropertyID : : FlexGrow ,  PropertyID : : FlexBasis ,  PropertyID : : Flex  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  property_and_value  =  TRY ( parse_css_value_for_properties ( properties ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! property_and_value . style_value ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  value  =  property_and_value . style_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( property_and_value . property )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : FlexGrow :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-19 10:08:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // NOTE: The spec says that flex-basis should be 0 here, but other engines currently use 0%.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // https://github.com/w3c/csswg-drafts/issues/5742
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-07 17:16:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  flex_basis  =  TRY ( PercentageStyleValue : : create ( Percentage ( 0 ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:10:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  one  =  TRY ( NumberStyleValue : : create ( 1 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 12:22:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FlexStyleValue : : create ( * value ,  one ,  flex_basis ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : FlexBasis :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:10:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  one  =  TRY ( NumberStyleValue : : create ( 1 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  FlexStyleValue : : create ( one ,  one ,  * value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : Flex :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( value - > is_identifier ( )  & &  value - > to_identifier ( )  = =  ValueID : : None )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:10:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  zero  =  TRY ( NumberStyleValue : : create ( 0 ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  FlexStyleValue : : create ( zero ,  zero ,  TRY ( IdentifierStyleValue : : create ( ValueID : : Auto ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-19 14:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-19 14:36:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-19 10:08:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  flex_grow ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  flex_shrink ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  flex_basis ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: FlexGrow has to be before FlexBasis. `0` is a valid FlexBasis, but only
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //       if FlexGrow (along with optional FlexShrink) have already been specified.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  remaining_longhands  =  Vector  {  PropertyID : : FlexGrow ,  PropertyID : : FlexBasis  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  property_and_value  =  TRY ( parse_css_value_for_properties ( remaining_longhands ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! property_and_value . style_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  value  =  property_and_value . style_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remove_property ( remaining_longhands ,  property_and_value . property ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( property_and_value . property )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : FlexGrow :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! flex_grow ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            flex_grow  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Flex-shrink may optionally follow directly after.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_flex_shrink  =  TRY ( parse_css_value_for_property ( PropertyID : : FlexShrink ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( maybe_flex_shrink ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                flex_shrink  =  maybe_flex_shrink . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : FlexBasis :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! flex_basis ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            flex_basis  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 16:21:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! flex_grow ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        flex_grow  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : FlexGrow ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! flex_shrink ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        flex_shrink  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : FlexShrink ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-07 17:16:49 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! flex_basis )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: The spec says that flex-basis should be 0 here, but other engines currently use 0%.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // https://github.com/w3c/csswg-drafts/issues/5742
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        flex_basis  =  TRY ( PercentageStyleValue : : create ( Percentage ( 0 ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  FlexStyleValue : : create ( flex_grow . release_nonnull ( ) ,  flex_shrink . release_nonnull ( ) ,  flex_basis . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_flex_flow_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-08-05 17:19:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  >  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  flex_direction ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  flex_wrap ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 17:10:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  remaining_longhands  =  Vector  {  PropertyID : : FlexDirection ,  PropertyID : : FlexWrap  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  property_and_value  =  TRY ( parse_css_value_for_properties ( remaining_longhands ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! property_and_value . style_value ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 17:19:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 17:10:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  value  =  property_and_value . style_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remove_property ( remaining_longhands ,  property_and_value . property ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( property_and_value . property )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : FlexDirection : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! flex_direction ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 17:19:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            flex_direction  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 17:10:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : FlexWrap : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! flex_wrap ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 17:19:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            flex_wrap  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-18 17:10:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 17:19:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! flex_direction ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        flex_direction  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : FlexDirection ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 17:19:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! flex_wrap ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        flex_wrap  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : FlexWrap ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 17:19:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  FlexFlowStyleValue : : create ( flex_direction . release_nonnull ( ) ,  flex_wrap . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 17:19:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  is_generic_font_family ( ValueID  identifier )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( identifier )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : Cursive : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : Fantasy : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : Monospace : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : Serif : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : SansSerif : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : UiMonospace : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : UiRounded : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : UiSerif : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  ValueID : : UiSansSerif : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_font_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-02-03 14:27:09 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  font_stretch ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  font_style ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  font_weight ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  font_size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  line_height ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  font_families ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 14:54:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  font_variant ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Handle system fonts. (caption, icon, menu, message-box, small-caption, status-bar)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Several sub-properties can be "normal", and appear in any order: style, variant, weight, stretch
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // So, we have to handle that separately.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    int  normal_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  remaining_longhands  =  Vector  {  PropertyID : : FontSize ,  PropertyID : : FontStretch ,  PropertyID : : FontStyle ,  PropertyID : : FontVariant ,  PropertyID : : FontWeight  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  peek_token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( peek_token . is ( Token : : Type : : Ident )  & &  value_id_from_string ( peek_token . token ( ) . ident ( ) )  = =  ValueID : : Normal )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            normal_count + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  property_and_value  =  TRY ( parse_css_value_for_properties ( remaining_longhands ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! property_and_value . style_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  value  =  property_and_value . style_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remove_property ( remaining_longhands ,  property_and_value . property ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( property_and_value . property )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : FontSize :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! font_size ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            font_size  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Consume `/ line-height` if present
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( tokens . peek_token ( ) . is_delim ( ' / ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  maybe_line_height  =  TRY ( parse_css_value_for_property ( PropertyID : : LineHeight ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! maybe_line_height ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                line_height  =  maybe_line_height . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Consume font-families
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_font_families  =  TRY ( parse_font_family_value ( tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // font-family comes last, so we must not have any tokens left over.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_font_families  | |  tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            font_families  =  maybe_font_families . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : FontStretch :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! font_stretch ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 14:27:09 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            font_stretch  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : FontStyle :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: Handle angle parameter to `oblique`: https://www.w3.org/TR/css-fonts-4/#font-style-prop
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! font_style ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            font_style  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : FontVariant :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! font_variant ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            font_variant  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : FontWeight :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! font_weight ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            font_weight  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Since normal is the default value for all the properties that can have it, we don't have to actually
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // set anything to normal here. It'll be set when we create the FontStyleValue below.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // We just need to make sure we were not given more normals than will fit.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-04 15:13:33 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    int  unset_value_count  =  ( font_style  ?  0  :  1 )  +  ( font_weight  ?  0  :  1 )  +  ( font_variant  ?  0  :  1 )  +  ( font_stretch  ?  0  :  1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( unset_value_count  <  normal_count ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! font_size  | |  ! font_families ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-03 14:27:09 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! font_stretch ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        font_stretch  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : FontStretch ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! font_style ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        font_style  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : FontStyle ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! font_weight ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        font_weight  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : FontWeight ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! line_height ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        line_height  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : LineHeight ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  FontStyleValue : : create ( font_stretch . release_nonnull ( ) ,  font_style . release_nonnull ( ) ,  font_weight . release_nonnull ( ) ,  font_size . release_nonnull ( ) ,  line_height . release_nonnull ( ) ,  font_families . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_font_family_value ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  next_is_comma_or_eof  =  [ & ] ( )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ! tokens . has_next_token ( )  | |  tokens . peek_token ( ) . is ( Token : : Type : : Comma ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Note: Font-family names can either be a quoted string, or a keyword, or a series of custom-idents.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // eg, these are equivalent:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //     font-family: my cool     font\!, serif;
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //     font-family: "my cool font!", serif;
 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 00:41:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  font_families ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-04 18:02:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < DeprecatedString >  current_name_parts ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  peek  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( peek . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // `font-family: my cool "font";` is invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! current_name_parts . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ;  // String
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! next_is_comma_or_eof ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( font_families . try_append ( TRY ( StringStyleValue : : create ( TRY ( String : : from_utf8 ( peek . token ( ) . string ( ) ) ) ) ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ;  // Comma
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( peek . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // If this is a valid identifier, it's NOT a custom-ident and can't be part of a larger name.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // CSS-wide keywords are not allowed
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  builtin  =  TRY ( parse_builtin_value ( peek ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_ident  =  value_id_from_string ( peek . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Can't have a generic-font-name as a token in an unquoted font name.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( maybe_ident . has_value ( )  & &  is_generic_font_family ( maybe_ident . value ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! current_name_parts . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                ( void ) tokens . next_token ( ) ;  // Ident
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! next_is_comma_or_eof ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                TRY ( font_families . try_append ( TRY ( IdentifierStyleValue : : create ( maybe_ident . value ( ) ) ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                ( void ) tokens . next_token ( ) ;  // Comma
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( current_name_parts . try_append ( tokens . next_token ( ) . token ( ) . ident ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( peek . is ( Token : : Type : : Comma ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( current_name_parts . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ;  // Comma
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( font_families . try_append ( TRY ( StringStyleValue : : create ( TRY ( String : : join ( '   ' ,  current_name_parts ) ) ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            current_name_parts . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Can't have a trailing comma
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:13:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! current_name_parts . is_empty ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( font_families . try_append ( TRY ( StringStyleValue : : create ( TRY ( String : : join ( '   ' ,  current_name_parts ) ) ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 17:01:26 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        current_name_parts . clear ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( font_families . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  StyleValueList : : create ( move ( font_families ) ,  StyleValueList : : Separator : : Comma ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-07 15:46:44 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								CSSRule *  Parser : : parse_font_face_rule ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  declarations_and_at_rules  =  parse_a_list_of_declarations ( tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:13:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < FlyString >  font_family ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < FontFace : : Source >  src ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 16:39:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < UnicodeRange >  unicode_range ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 15:35:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < int >  weight ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < int >  slope ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  declaration_or_at_rule  :  declarations_and_at_rules )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( declaration_or_at_rule . is_at_rule ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 14:35:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: CSS at-rules are not allowed in @font-face; discarding. " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  declaration  =  declaration_or_at_rule . declaration ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 15:35:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( declaration . name ( ) . equals_ignoring_ascii_case ( " font-weight " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TokenStream  token_stream  {  declaration . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  value  =  parse_css_value ( CSS : : PropertyID : : FontWeight ,  token_stream ) ;  ! value . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                weight  =  value . value ( ) - > to_font_weight ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( declaration . name ( ) . equals_ignoring_ascii_case ( " font-style " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TokenStream  token_stream  {  declaration . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  value  =  parse_css_value ( CSS : : PropertyID : : FontStyle ,  token_stream ) ;  ! value . is_error ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                slope  =  value . value ( ) - > to_font_slope ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( declaration . name ( ) . equals_ignoring_ascii_case ( " font-family " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: This is very similar to, but different from, the logic in parse_font_family_value().
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            //        Ideally they could share code.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-12-04 18:02:33 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Vector < DeprecatedString >  font_family_parts ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            bool  had_syntax_error  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 14:41:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( size_t  i  =  0 ;  i  <  declaration . values ( ) . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  const &  part  =  declaration . values ( ) [ i ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( part . is ( Token : : Type : : Whitespace ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( part . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! font_family_parts . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face font-family format invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        had_syntax_error  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    font_family_parts . append ( part . token ( ) . string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( part . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 20:14:21 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( is_builtin ( part . token ( ) . ident ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face font-family format invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        had_syntax_error  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  value_id  =  value_id_from_string ( part . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-10 12:43:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( value_id . has_value ( )  & &  is_generic_font_family ( value_id . value ( ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face font-family format invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        had_syntax_error  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    font_family_parts . append ( part . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face font-family format invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                had_syntax_error  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( had_syntax_error  | |  font_family_parts . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:13:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            font_family  =  String : : join ( '   ' ,  font_family_parts ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( declaration . name ( ) . equals_ignoring_ascii_case ( " src " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 14:41:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            TokenStream  token_stream  {  declaration . values ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 21:18:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Vector < FontFace : : Source >  supported_sources  =  parse_font_face_src ( token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! supported_sources . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                src  =  move ( supported_sources ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 16:39:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( declaration . name ( ) . equals_ignoring_ascii_case ( " unicode-range " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 16:39:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Vector < UnicodeRange >  unicode_ranges ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            bool  unicode_range_invalid  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TokenStream  all_tokens  {  declaration . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  range_token_lists  =  parse_a_comma_separated_list_of_component_values ( all_tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto &  range_tokens  :  range_token_lists )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                TokenStream  range_token_stream  {  range_tokens  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  maybe_unicode_range  =  parse_unicode_range ( range_token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! maybe_unicode_range . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face unicode-range format invalid; discarding. " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    unicode_range_invalid  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                unicode_ranges . append ( maybe_unicode_range . release_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( unicode_range_invalid  | |  unicode_ranges . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            unicode_range  =  move ( unicode_ranges ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 14:35:22 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Unrecognized descriptor '{}' in @font-face; discarding. " ,  declaration . name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! font_family . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: Failed to parse @font-face: no font-family! " ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 16:39:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( unicode_range . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        unicode_range . empend ( 0x0u ,  0x10FFFFu ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 15:35:04 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  CSSFontFaceRule : : create ( m_context . realm ( ) ,  FontFace  {  font_family . release_value ( ) ,  weight ,  slope ,  move ( src ) ,  move ( unicode_range )  } ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 21:18:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Vector < FontFace : : Source >  Parser : : parse_font_face_src ( TokenStream < ComponentValue > &  component_values )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: Get this information from the system somehow?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Format-name table: https://www.w3.org/TR/css-fonts-4/#font-format-definitions
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  font_format_is_supported  =  [ ] ( StringView  name )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The spec requires us to treat opentype and truetype as synonymous.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( name . is_one_of_ignoring_ascii_case ( " opentype " sv ,  " truetype " sv ,  " woff " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 21:18:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < FontFace : : Source >  supported_sources ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  list_of_source_token_lists  =  parse_a_comma_separated_list_of_component_values ( component_values ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  source_token_list  :  list_of_source_token_lists )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TokenStream  source_tokens  {  source_token_list  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        source_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  first  =  source_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 21:18:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <url> [ format(<font-format>)]?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Implement optional tech() function from CSS-Fonts-4.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-14 21:14:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_url  =  parse_url_function ( first ,  AllowedDataUrlType : : Font ) ;  maybe_url . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 21:18:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  url  =  maybe_url . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
											
												LibWeb: Load alternative font urls if others fail
We don't support all parts of the font formats we assume as "supported"
in the CSS parser. For example, if an open type font has a CFF table, we
reject loading it. This meant that until now, when such an
unsupported-supported font url was first in the list of urls, we
couldn't load it at all, even when we would support a later url.
To resolve that, try loading all font urls one after each other, in case
we are not able to load the higher priority one.
This also resolves a FIXME related to spec compliant url prioritization.
Our CSS parser already filters and prioritizes font src urls in
compliance with the spec. However, we still had to resort to brittle
file extension matching, because some websites don't set the `format`
and if the first url in a src list happened to be one we don't support,
the font could not be loaded at all. This now is unnecessary because we
can try and discard the urls instead.
											 
										 
										
											2023-03-18 12:44:10 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! url . is_valid ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:13:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Optional < FlyString >  format ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 21:18:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            source_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! source_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                supported_sources . empend ( move ( url ) ,  format ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_function  =  source_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_function . is_function ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face src invalid (token after `url()` that isn't a function: {}); discarding. " ,  maybe_function . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  function  =  maybe_function . function ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( function . name ( ) . equals_ignoring_ascii_case ( " format " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 21:18:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                TokenStream  format_tokens  {  function . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                format_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  const &  format_name_token  =  format_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 21:18:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                StringView  format_name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( format_name_token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    format_name  =  format_name_token . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  if  ( format_name_token . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    format_name  =  format_name_token . token ( ) . string ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face src invalid (`format()` parameter not an ident or string; is: {}); discarding. " ,  format_name_token . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! font_format_is_supported ( format_name ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face src format({}) not supported; skipping. " ,  format_name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-18 15:13:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                format  =  FlyString : : from_utf8 ( format_name ) . release_value_but_fixme_should_propagate_errors ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 21:18:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face src invalid (unrecognized function token `{}`); discarding. " ,  function . name ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            source_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( source_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face src invalid (extra token `{}`); discarding. " ,  source_tokens . peek_token ( ) . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            supported_sources . empend ( move ( url ) ,  format ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Implement `local()`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " CSSParser: @font-face src invalid (failed to parse url from: {}); discarding. " ,  first . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 21:18:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  supported_sources ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_list_style_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  >  3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  list_position ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  list_image ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  list_type ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    int  found_nones  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:09:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < PropertyID >  remaining_longhands  {  PropertyID : : ListStyleImage ,  PropertyID : : ListStylePosition ,  PropertyID : : ListStyleType  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:09:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  peek  =  tokens . peek_token ( ) ;  peek . is ( Token : : Type : : Ident )  & &  peek . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " none " sv ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            found_nones + + ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:09:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  property_and_value  =  TRY ( parse_css_value_for_properties ( remaining_longhands ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! property_and_value . style_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  value  =  property_and_value . style_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remove_property ( remaining_longhands ,  property_and_value . property ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( property_and_value . property )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : ListStylePosition :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! list_position ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            list_position  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:09:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : ListStyleImage :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! list_image ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            list_image  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:09:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : ListStyleType :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! list_type ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            list_type  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:09:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( found_nones  >  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( found_nones  = =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( list_image  | |  list_type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  none  =  TRY ( IdentifierStyleValue : : create ( ValueID : : None ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        list_image  =  none ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        list_type  =  none ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( found_nones  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( list_image  & &  list_type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  none  =  TRY ( IdentifierStyleValue : : create ( ValueID : : None ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! list_image ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            list_image  =  none ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! list_type ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            list_type  =  none ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! list_position ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        list_position  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : ListStylePosition ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! list_image ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        list_image  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : ListStyleImage ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! list_type ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        list_type  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : ListStyleType ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  ListStyleStyleValue : : create ( list_position . release_nonnull ( ) ,  list_image . release_nonnull ( ) ,  list_type . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_overflow_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:15:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:15:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_value  =  TRY ( parse_css_value_for_property ( PropertyID : : Overflow ,  tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:15:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  OverflowStyleValue : : create ( * maybe_value ,  * maybe_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  2 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:15:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_x_value  =  TRY ( parse_css_value_for_property ( PropertyID : : OverflowX ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_y_value  =  TRY ( parse_css_value_for_property ( PropertyID : : OverflowY ,  tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_x_value  | |  ! maybe_y_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:15:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  OverflowStyleValue : : create ( maybe_x_value . release_nonnull ( ) ,  maybe_y_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 16:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_place_content_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  >  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_align_content_value  =  TRY ( parse_css_value_for_property ( PropertyID : : AlignContent ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_align_content_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! property_accepts_identifier ( PropertyID : : JustifyContent ,  maybe_align_content_value - > to_identifier ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  PlaceContentStyleValue : : create ( * maybe_align_content_value ,  * maybe_align_content_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_justify_content_value  =  TRY ( parse_css_value_for_property ( PropertyID : : JustifyContent ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_justify_content_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  PlaceContentStyleValue : : create ( maybe_align_content_value . release_nonnull ( ) ,  maybe_justify_content_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_text_decoration_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  decoration_line ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 02:09:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  decoration_thickness ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  decoration_style ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    RefPtr < StyleValue >  decoration_color ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:33:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  remaining_longhands  =  Vector  {  PropertyID : : TextDecorationColor ,  PropertyID : : TextDecorationLine ,  PropertyID : : TextDecorationStyle ,  PropertyID : : TextDecorationThickness  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:33:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:33:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  property_and_value  =  TRY ( parse_css_value_for_properties ( remaining_longhands ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! property_and_value . style_value ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:33:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  value  =  property_and_value . style_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        remove_property ( remaining_longhands ,  property_and_value . property ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:33:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( property_and_value . property )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : TextDecorationColor :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! decoration_color ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            decoration_color  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:33:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : TextDecorationLine :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! decoration_line ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  parsed_decoration_line  =  TRY ( parse_text_decoration_line_value ( tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! parsed_decoration_line ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            decoration_line  =  parsed_decoration_line . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:33:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : TextDecorationThickness :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! decoration_thickness ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 02:09:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            decoration_thickness  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:33:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  PropertyID : : TextDecorationStyle :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( ! decoration_style ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            decoration_style  =  value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:33:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! decoration_line ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        decoration_line  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : TextDecorationLine ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-06 02:09:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! decoration_thickness ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        decoration_thickness  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : TextDecorationThickness ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! decoration_style ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        decoration_style  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : TextDecorationStyle ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! decoration_color ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 15:09:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        decoration_color  =  TRY ( property_initial_value ( m_context . realm ( ) ,  PropertyID : : TextDecorationColor ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  TextDecorationStyleValue : : create ( decoration_line . release_nonnull ( ) ,  decoration_thickness . release_nonnull ( ) ,  decoration_style . release_nonnull ( ) ,  decoration_color . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_text_decoration_line_value ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-02-20 00:41:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  style_values ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:24:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_value  =  TRY ( parse_css_value_for_property ( PropertyID : : TextDecorationLine ,  tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_value ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  value  =  maybe_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_line  =  value_id_to_text_decoration_line ( value - > to_identifier ( ) ) ;  maybe_line . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:24:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( maybe_line  = =  TextDecorationLine : : None )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! style_values . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:24:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( style_values . contains_slow ( value ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:24:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( style_values . try_append ( move ( value ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( style_values . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  StyleValueList : : create ( move ( style_values ) ,  StyleValueList : : Separator : : Space ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-06 02:29:36 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_easing_value ( TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  part  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StringView  name ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < Vector < ComponentValue >  const & >  arguments ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( part . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        name  =  part . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( part . is_function ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        name  =  part . function ( ) . name ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        arguments  =  part . function ( ) . values ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  maybe_function  =  easing_function_from_string ( name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! maybe_function . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  function  =  maybe_function . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  function_metadata  =  easing_function_metadata ( function ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function_metadata . parameters . is_empty ( )  & &  arguments . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Too many arguments to {}. max: 0 " ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    size_t  argument_index  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( arguments . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  argument_tokens  =  TokenStream  {  * arguments  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  arguments_values  =  parse_a_comma_separated_list_of_component_values ( argument_tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( arguments_values . size ( )  >  function_metadata . parameters . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Too many arguments to {}. max: {} " ,  name ,  function_metadata . parameters . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto &  argument_values  :  arguments_values )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( argument_values . size ( )  ! =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " Too many values in argument to {}. max: 1 " ,  name ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  value  =  argument_values [ 0 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            switch  ( function_metadata . parameters [ argument_index ] . type )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  EasingFunctionParameterType : : Number :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( value . is ( Token : : Type : : Number ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    values . append ( TRY ( NumberStyleValue : : create ( value . token ( ) . number ( ) . value ( ) ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  EasingFunctionParameterType : : NumberZeroToOne :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( value . is ( Token : : Type : : Number )  & &  value . token ( ) . number_value ( )  > =  0  & &  value . token ( ) . number_value ( )  < =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    values . append ( TRY ( NumberStyleValue : : create ( value . token ( ) . number ( ) . value ( ) ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  EasingFunctionParameterType : : Integer :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( value . is ( Token : : Type : : Number )  & &  value . token ( ) . number ( ) . is_integer ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    values . append ( TRY ( IntegerStyleValue : : create ( value . token ( ) . number ( ) . integer_value ( ) ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  EasingFunctionParameterType : : StepPosition :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! value . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  ident  =  TRY ( parse_identifier_value ( value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! ident ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                switch  ( ident - > to_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  ValueID : : JumpStart : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  ValueID : : JumpEnd : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  ValueID : : JumpNone : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  ValueID : : Start : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                case  ValueID : : End : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    TRY ( values . try_append ( * ident ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            + + argument_index ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( argument_index  <  function_metadata . parameters . size ( )  & &  ! function_metadata . parameters [ argument_index ] . is_optional )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Required parameter at position {} is missing " ,  argument_index ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  EasingStyleValue : : create ( function ,  move ( values ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_transform_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2021-09-18 17:20:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-02-20 00:41:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  transformations ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 19:33:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  part  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 17:20:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( part . is ( Token : : Type : : Ident )  & &  part . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " none " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-10 13:47:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! transformations . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 19:33:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  IdentifierStyleValue : : create ( ValueID : : None ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-10 13:47:09 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 17:20:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! part . is_function ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 15:52:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_function  =  transform_function_from_string ( part . function ( ) . name ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 17:20:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! maybe_function . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 17:37:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  function  =  maybe_function . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  function_metadata  =  transform_function_metadata ( function ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 17:20:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 00:41:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        StyleValueVector  values ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 19:49:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  argument_tokens  =  TokenStream  {  part . function ( ) . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        argument_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-26 16:09:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        size_t  argument_index  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 19:49:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        while  ( argument_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-26 16:09:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( argument_index  = =  function_metadata . parameters . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                dbgln_if ( CSS_PARSER_DEBUG ,  " Too many arguments to {}. max: {} " ,  part . function ( ) . name ( ) ,  function_metadata . parameters . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  value  =  argument_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 13:49:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            RefPtr < CalculatedStyleValue >  maybe_calc_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  maybe_dynamic_value  =  TRY ( parse_dynamic_value ( value ) ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 13:49:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                // TODO: calc() is the only dynamic value we support for now, but more will come later.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // FIXME: Actually, calc() should probably be parsed inside parse_dimension_value() etc,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                //        so that it affects every use instead of us having to manually implement it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                VERIFY ( maybe_dynamic_value - > is_calculated ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                maybe_calc_value  =  maybe_dynamic_value - > as_calculated ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 17:37:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-26 16:09:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            switch  ( function_metadata . parameters [ argument_index ] . type )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 17:37:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  TransformFunctionParameterType : : Angle :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // These are `<angle> | <zero>` in the spec, so we have to check for both kinds.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 13:49:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( maybe_calc_value  & &  maybe_calc_value - > resolves_to_angle ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-30 15:33:37 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    values . append ( maybe_calc_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 13:49:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  if  ( value . is ( Token : : Type : : Number )  & &  value . token ( ) . number_value ( )  = =  0 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    values . append ( TRY ( AngleStyleValue : : create ( Angle : : make_degrees ( 0 ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 17:37:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  dimension_value  =  TRY ( parse_dimension_value ( value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 17:37:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! dimension_value  | |  ! dimension_value - > is_angle ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    values . append ( dimension_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-28 02:46:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  TransformFunctionParameterType : : Length :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( maybe_calc_value  & &  maybe_calc_value - > resolves_to_length ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-30 15:46:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    values . append ( maybe_calc_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-28 02:46:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  dimension_value  =  TRY ( parse_dimension_value ( value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-28 02:46:27 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! dimension_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( dimension_value - > is_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        values . append ( dimension_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 17:37:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  TransformFunctionParameterType : : LengthPercentage :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 13:49:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( maybe_calc_value  & &  maybe_calc_value - > resolves_to_length ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-30 15:46:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    values . append ( maybe_calc_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 13:49:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  dimension_value  =  TRY ( parse_dimension_value ( value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 13:49:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! dimension_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 17:37:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 13:49:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( dimension_value - > is_percentage ( )  | |  dimension_value - > is_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        values . append ( dimension_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 17:37:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  TransformFunctionParameterType : : Number :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 13:49:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( maybe_calc_value  & &  maybe_calc_value - > resolves_to_number ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-30 15:46:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    values . append ( maybe_calc_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 13:49:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:01:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    // FIXME: Remove this reconsume once all parsing functions are TokenStream-based.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    argument_tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  number  =  TRY ( parse_number_value ( argument_tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-20 13:49:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( ! number ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    values . append ( number . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 17:37:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 17:20:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-17 16:53:19 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 19:49:46 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            argument_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( argument_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // Arguments must be separated by commas.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! argument_tokens . next_token ( ) . is ( Token : : Type : : Comma ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                argument_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // If there are no more parameters after the comma, this is invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! argument_tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 17:20:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-26 16:09:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            argument_index + + ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 17:37:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-26 16:09:20 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( argument_index  <  function_metadata . parameters . size ( )  & &  function_metadata . parameters [ argument_index ] . required )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Required parameter at position {} is missing " ,  argument_index ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-17 17:37:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        transformations . append ( TRY ( TransformationStyleValue : : create ( function ,  move ( values ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 17:20:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  StyleValueList : : create ( move ( transformations ) ,  StyleValueList : : Separator : : Space ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 17:20:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-transforms-1/#propdef-transform-origin
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// FIXME: This only supports a 2D position
  
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_transform_origin_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    enum  class  Axis  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        None , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        X , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Y , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    struct  AxisOffset  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Axis  axis ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        NonnullRefPtr < StyleValue >  offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  to_axis_offset  =  [ ] ( RefPtr < StyleValue >  value )  - >  ErrorOr < Optional < AxisOffset > >  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value - > is_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  AxisOffset  {  Axis : : None ,  value - > as_percentage ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value - > is_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  AxisOffset  {  Axis : : None ,  value - > as_length ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value - > is_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            switch  ( value - > to_identifier ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Top : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  AxisOffset  {  Axis : : Y ,  TRY ( PercentageStyleValue : : create ( Percentage ( 0 ) ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Left : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  AxisOffset  {  Axis : : X ,  TRY ( PercentageStyleValue : : create ( Percentage ( 0 ) ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Center : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  AxisOffset  {  Axis : : None ,  TRY ( PercentageStyleValue : : create ( Percentage ( 50 ) ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Bottom : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  AxisOffset  {  Axis : : Y ,  TRY ( PercentageStyleValue : : create ( Percentage ( 100 ) ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            case  ValueID : : Right : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  AxisOffset  {  Axis : : X ,  TRY ( PercentageStyleValue : : create ( Percentage ( 100 ) ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            default : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  OptionalNone  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  OptionalNone  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  make_list  =  [ ] ( NonnullRefPtr < StyleValue >  const &  x_value ,  NonnullRefPtr < StyleValue >  const &  y_value )  - >  ErrorOr < NonnullRefPtr < StyleValueList > >  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-02-20 00:41:51 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        StyleValueVector  values ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        values . append ( x_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        values . append ( y_value ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  StyleValueList : : create ( move ( values ) ,  StyleValueList : : Separator : : Space ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:44:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( component_values . size ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  1 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:44:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  single_value  =  TRY ( to_axis_offset ( TRY ( parse_css_value_for_property ( PropertyID : : TransformOrigin ,  tokens ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! single_value . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // If only one value is specified, the second value is assumed to be center.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: If one or two values are specified, the third value is assumed to be 0px.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        switch  ( single_value - > axis )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  Axis : : None : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        case  Axis : : X : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_list ( single_value - > offset ,  TRY ( PercentageStyleValue : : create ( Percentage ( 50 ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        case  Axis : : Y : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  make_list ( TRY ( PercentageStyleValue : : create ( Percentage ( 50 ) ) ) ,  single_value - > offset ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  2 :  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 17:44:12 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  first_value  =  TRY ( to_axis_offset ( TRY ( parse_css_value_for_property ( PropertyID : : TransformOrigin ,  tokens ) ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  second_value  =  TRY ( to_axis_offset ( TRY ( parse_css_value_for_property ( PropertyID : : TransformOrigin ,  tokens ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! first_value . has_value ( )  | |  ! second_value . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        RefPtr < StyleValue >  x_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        RefPtr < StyleValue >  y_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first_value - > axis  = =  Axis : : X )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            x_value  =  first_value - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( first_value - > axis  = =  Axis : : Y )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            y_value  =  first_value - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( second_value - > axis  = =  Axis : : X )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( x_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            x_value  =  second_value - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Put the other in Y since its axis can't have been X
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            y_value  =  first_value - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( second_value - > axis  = =  Axis : : Y )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( y_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            y_value  =  second_value - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // Put the other in X since its axis can't have been Y
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            x_value  =  first_value - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( x_value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                VERIFY ( ! y_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                y_value  =  second_value - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                VERIFY ( ! x_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                x_value  =  second_value - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // If two or more values are defined and either no value is a keyword, or the only used keyword is center,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // then the first value represents the horizontal position (or offset) and the second represents the vertical position (or offset).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: A third value always represents the Z position (or offset) and must be of type <length>.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( first_value - > axis  = =  Axis : : None  & &  second_value - > axis  = =  Axis : : None )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            x_value  =  first_value - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            y_value  =  second_value - > offset ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  make_list ( x_value . release_nonnull ( ) ,  y_value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_as_css_value ( PropertyID  property_id )  
						 
					
						
							
								
									
										
										
										
											2021-07-30 17:48:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-03-30 12:39:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  component_values  =  parse_a_list_of_component_values ( m_token_stream ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-30 17:48:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream ( component_values ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parsed_value  =  parse_css_value ( property_id ,  tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parsed_value . is_error ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  parsed_value . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-30 17:48:23 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < CSS : : GridSize >  Parser : : parse_grid_size ( ComponentValue  const &  component_value )  
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:49:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-05-10 23:46:33 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_value . is_function ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-21 03:07:28 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_dynamic  =  parse_dynamic_value ( component_value ) ;  ! maybe_dynamic . is_error ( )  & &  maybe_dynamic . value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  GridSize ( LengthPercentage ( maybe_dynamic . release_value ( ) - > as_calculated ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 12:58:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-10 23:46:33 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  token  =  component_value . token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( token . is ( Token : : Type : : Dimension )  & &  token . dimension_unit ( ) . equals_ignoring_ascii_case ( " fr " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        float  numeric_value  =  token . dimension_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( numeric_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  GridSize ( numeric_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( token . is ( Token : : Type : : Ident )  & &  token . ident ( ) . equals_ignoring_ascii_case ( " auto " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  GridSize : : make_auto ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( token . is ( Token : : Type : : Ident )  & &  token . ident ( ) . equals_ignoring_ascii_case ( " max-content " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:33:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  GridSize ( GridSize : : Type : : MaxContent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( token . is ( Token : : Type : : Ident )  & &  token . ident ( ) . equals_ignoring_ascii_case ( " min-content " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:33:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  GridSize ( GridSize : : Type : : MinContent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  dimension  =  parse_dimension ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! dimension . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( dimension - > is_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  GridSize ( dimension - > length ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    else  if  ( dimension - > is_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  GridSize ( dimension - > percentage ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2022-10-15 12:58:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < CSS : : GridMinMax >  Parser : : parse_min_max ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://www.w3.org/TR/css-grid-2/#valdef-grid-template-columns-minmax
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 'minmax(min, max)'
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Defines a size range greater than or equal to min and less than or equal to max. If the max is
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // less than the min, then the max will be floored by the min (essentially yielding minmax(min,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // min)). As a maximum, a <flex> value sets the track’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  function_tokens  =  TokenStream ( component_values ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  comma_separated_list  =  parse_a_comma_separated_list_of_component_values ( function_tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( comma_separated_list . size ( )  ! =  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  part_one_tokens  {  comma_separated_list [ 0 ]  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    part_one_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! part_one_tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  current_token  =  part_one_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  min_grid_size  =  parse_grid_size ( current_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  part_two_tokens  {  comma_separated_list [ 1 ]  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    part_two_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! part_two_tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    current_token  =  part_two_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  max_grid_size  =  parse_grid_size ( current_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( min_grid_size . has_value ( )  & &  max_grid_size . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 13:04:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // https://www.w3.org/TR/css-grid-2/#valdef-grid-template-columns-minmax
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								        // As a maximum, a <flex> value sets the track’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( min_grid_size . value ( ) . is_flexible_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  CSS : : GridMinMax ( min_grid_size . value ( ) ,  max_grid_size . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Optional < CSS : : GridRepeat >  Parser : : parse_repeat ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://www.w3.org/TR/css-grid-2/#repeat-syntax
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 7.2.3.1. Syntax of repeat()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The generic form of the repeat() syntax is, approximately,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // repeat( [ <integer [1,∞]> | auto-fill | auto-fit ] , <track-list> )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_auto_fill  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_auto_fit  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  function_tokens  =  TokenStream ( component_values ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  comma_separated_list  =  parse_a_comma_separated_list_of_component_values ( function_tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( comma_separated_list . size ( )  ! =  2 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The first argument specifies the number of repetitions.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  part_one_tokens  {  comma_separated_list [ 0 ]  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    part_one_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! part_one_tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  current_token  =  part_one_tokens . next_token ( ) . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  repeat_count  =  0 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( current_token . is ( Token : : Type : : Number )  & &  current_token . number ( ) . is_integer ( )  & &  current_token . number_value ( )  >  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        repeat_count  =  current_token . number_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    else  if  ( current_token . is ( Token : : Type : : Ident )  & &  current_token . ident ( ) . equals_ignoring_ascii_case ( " auto-fill " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        is_auto_fill  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    else  if  ( current_token . is ( Token : : Type : : Ident )  & &  current_token . ident ( ) . equals_ignoring_ascii_case ( " auto-fit " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        is_auto_fit  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The second argument is a track list, which is repeated that number of times.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  part_two_tokens  {  comma_separated_list [ 1 ]  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    part_two_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! part_two_tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < CSS : : ExplicitGridTrack >  repeat_params ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Vector < String > >  line_names_list ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  last_object_was_line_names  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( part_two_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  token  =  part_two_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        Vector < String >  line_names ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is_block ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( last_object_was_line_names ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            last_object_was_line_names  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! token . block ( ) . is_square ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TokenStream  block_tokens  {  token . block ( ) . values ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            while  ( block_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  current_block_token  =  block_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  maybe_string  =  String : : from_utf8 ( current_block_token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( maybe_string . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                line_names . append ( maybe_string . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 19:45:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                block_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            line_names_list . append ( line_names ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            part_two_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            last_object_was_line_names  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  track_sizing_function  =  parse_track_sizing_function ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! track_sizing_function . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // However, there are some restrictions:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								            // The repeat() notation can’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( track_sizing_function . value ( ) . is_repeat ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 13:04:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // Automatic repetitions (auto-fill or auto-fit) cannot be combined with intrinsic or flexible sizes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( track_sizing_function . value ( ) . is_default ( )  & &  track_sizing_function . value ( ) . grid_size ( ) . is_flexible_length ( )  & &  ( is_auto_fill  | |  is_auto_fit ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            repeat_params . append ( track_sizing_function . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            part_two_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 13:04:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( line_names_list . size ( )  < =  repeat_params . size ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        line_names_list . append ( { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-15 13:04:24 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Thus the precise syntax of the repeat() notation has several forms:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <track-repeat> = repeat( [ <integer [1,∞]> ] , [ <line-names>? <track-size> ]+ <line-names>? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <auto-repeat>  = repeat( [ auto-fill | auto-fit ] , [ <line-names>? <fixed-size> ]+ <line-names>? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <fixed-repeat> = repeat( [ <integer [1,∞]> ] , [ <line-names>? <fixed-size> ]+ <line-names>? )
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <name-repeat>  = repeat( [ <integer [1,∞]> | auto-fill ], <line-names>+)
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-08 14:05:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // The <track-repeat> variant can represent the repetition of any <track-size>, but is limited to a
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // fixed number of repetitions.
 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-08 14:05:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // The <auto-repeat> variant can repeat automatically to fill a space, but requires definite track
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // sizes so that the number of repetitions can be calculated. It can only appear once in the track
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // list, but the same track list can also contain <fixed-repeat>s.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The <name-repeat> variant is for adding line names to subgrids. It can only be used with the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // subgrid keyword and cannot specify track sizes, only line names.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // If a repeat() function that is not a <name-repeat> ends up placing two <line-names> adjacent to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // each other, the name lists are merged. For example, repeat(2, [a] 1fr [b]) is equivalent to [a]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // 1fr [b a] 1fr [b].
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_auto_fill ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  CSS : : GridRepeat ( CSS : : GridTrackSizeList ( repeat_params ,  line_names_list ) ,  CSS : : GridRepeat : : Type : : AutoFill ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    else  if  ( is_auto_fit ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  CSS : : GridRepeat ( CSS : : GridTrackSizeList ( repeat_params ,  line_names_list ) ,  CSS : : GridRepeat : : Type : : AutoFit ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    else 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  CSS : : GridRepeat ( CSS : : GridTrackSizeList ( repeat_params ,  line_names_list ) ,  repeat_count ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Optional < CSS : : ExplicitGridTrack >  Parser : : parse_track_sizing_function ( ComponentValue  const &  token )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( token . is_function ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  function_token  =  token . function ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( function_token . name ( ) . equals_ignoring_ascii_case ( " repeat " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_repeat  =  parse_repeat ( function_token . values ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( maybe_repeat . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  CSS : : ExplicitGridTrack ( maybe_repeat . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( function_token . name ( ) . equals_ignoring_ascii_case ( " minmax " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_min_max_value  =  parse_min_max ( function_token . values ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( maybe_min_max_value . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  CSS : : ExplicitGridTrack ( maybe_min_max_value . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-12 14:25:46 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  if  ( auto  maybe_dynamic  =  parse_dynamic_value ( token ) ;  ! maybe_dynamic . is_error ( )  & &  maybe_dynamic . value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  CSS : : ExplicitGridTrack ( GridSize ( LengthPercentage ( maybe_dynamic . release_value ( ) - > as_calculated ( ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-14 11:30:52 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( token . is ( Token : : Type : : Ident )  & &  token . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " auto " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  CSS : : ExplicitGridTrack ( GridSize ( Length : : make_auto ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  if  ( token . is_block ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  grid_size  =  parse_grid_size ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! grid_size . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  CSS : : ExplicitGridTrack ( grid_size . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_grid_track_size_list ( Vector < ComponentValue >  const &  component_values ,  bool  allow_separate_line_name_blocks )  
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-06-07 13:04:06 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  1  & &  component_values . first ( ) . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  TRY ( parse_identifier_value ( component_values . first ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident  & &  ident - > to_identifier ( )  = =  ValueID : : None )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  GridTrackSizeListStyleValue : : make_none ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < CSS : : ExplicitGridTrack >  track_list ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Vector < String > >  line_names_list ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  last_object_was_line_names  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  tokens  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is_block ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-29 19:32:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( last_object_was_line_names  & &  ! allow_separate_line_name_blocks ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  GridTrackSizeListStyleValue : : make_auto ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            last_object_was_line_names  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            Vector < String >  line_names ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! token . block ( ) . is_square ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  GridTrackSizeListStyleValue : : make_auto ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            TokenStream  block_tokens  {  token . block ( ) . values ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 03:13:52 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            block_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            while  ( block_tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  current_block_token  =  block_tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  maybe_string  =  String : : from_utf8 ( current_block_token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( maybe_string . is_error ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                line_names . append ( maybe_string . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-21 19:45:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                block_tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            line_names_list . append ( line_names ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            last_object_was_line_names  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  track_sizing_function  =  parse_track_sizing_function ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! track_sizing_function . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  GridTrackSizeListStyleValue : : make_auto ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: Handle multiple repeat values (should combine them here, or remove
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // any other ones if the first one is auto-fill, etc.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            track_list . append ( track_sizing_function . value ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:49:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:45:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( line_names_list . size ( )  < =  track_list . size ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        line_names_list . append ( { } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  GridTrackSizeListStyleValue : : create ( CSS : : GridTrackSizeList ( track_list ,  line_names_list ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:49:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-21 18:08:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_grid_auto_track_sizes ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://www.w3.org/TR/css-grid-2/#auto-tracks
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <track-size>+
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < CSS : : ExplicitGridTrack >  track_list ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream  tokens  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  track_sizing_function  =  parse_track_sizing_function ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! track_sizing_function . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  GridTrackSizeListStyleValue : : make_auto ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // FIXME: Handle multiple repeat values (should combine them here, or remove
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // any other ones if the first one is auto-fill, etc.)
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        track_list . append ( track_sizing_function . value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  GridTrackSizeListStyleValue : : create ( CSS : : GridTrackSizeList ( track_list ,  { } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_grid_track_placement ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // https://www.w3.org/TR/css-grid-2/#line-placement
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Line-based Placement: the grid-row-start, grid-column-start, grid-row-end, and grid-column-end properties
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <grid-line> =
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //     auto |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //     <custom-ident> |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //     [ <integer> && <custom-ident>? ] |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //     [ span && [ <integer> || <custom-ident> ] ]
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_auto  =  [ ] ( Token  token )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Ident )  & &  token . ident ( ) . equals_ignoring_ascii_case ( " auto " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_span  =  [ ] ( Token  token )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Ident )  & &  token . ident ( ) . equals_ignoring_ascii_case ( " span " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_valid_integer  =  [ ] ( Token  token )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // An <integer> value of zero makes the declaration invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Number )  & &  token . number ( ) . is_integer ( )  & &  token . number_value ( )  ! =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:46:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_line_name  =  [ ] ( Token  token )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // The <custom-ident> additionally excludes the keywords span and auto.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Ident )  & &  ! token . ident ( ) . equals_ignoring_ascii_case ( " span " sv )  & &  ! token . ident ( ) . equals_ignoring_ascii_case ( " auto " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:46:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  current_token  =  tokens . next_token ( ) . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_auto ( current_token ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  GridTrackPlacementStyleValue : : create ( CSS : : GridTrackPlacement ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_span ( current_token ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  GridTrackPlacementStyleValue : : create ( CSS : : GridTrackPlacement ( 1 ,  true ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_valid_integer ( current_token ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  GridTrackPlacementStyleValue : : create ( CSS : : GridTrackPlacement ( static_cast < int > ( current_token . number_value ( ) ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_line_name ( current_token ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_string  =  String : : from_utf8 ( current_token . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_string . is_error ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  GridTrackPlacementStyleValue : : create ( CSS : : GridTrackPlacement ( maybe_string . value ( ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  span_value  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  span_or_position_value  =  0 ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    String  line_name_value ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_auto ( current_token ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_span ( current_token ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( span_value  = =  false ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                span_value  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_valid_integer ( current_token ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( span_or_position_value  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                span_or_position_value  =  static_cast < int > ( current_token . number_value ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:46:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_line_name ( current_token ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( line_name_value . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                auto  maybe_string  =  String : : from_utf8 ( current_token . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( maybe_string . is_error ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                line_name_value  =  maybe_string . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 17:29:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:46:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            current_token  =  tokens . next_token ( ) . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 13:06:45 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Negative integers or zero are invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( span_value  & &  span_or_position_value  <  1 ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:27:57 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // If the <integer> is omitted, it defaults to 1.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( span_or_position_value  = =  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        span_or_position_value  =  1 ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-30 13:46:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! line_name_value . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  GridTrackPlacementStyleValue : : create ( CSS : : GridTrackPlacement ( line_name_value ,  span_or_position_value ,  span_value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  GridTrackPlacementStyleValue : : create ( CSS : : GridTrackPlacement ( span_or_position_value ,  span_value ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_grid_track_placement_shorthand_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2022-08-23 20:00:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  current_token  =  tokens . next_token ( ) . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 13:50:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  track_start_placement_tokens ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( current_token . is ( Token : : Type : : Delim )  & &  current_token . delim ( )  = =  " / " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        track_start_placement_tokens . append ( current_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        current_token  =  tokens . next_token ( ) . token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 20:00:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 13:50:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  track_end_placement_tokens ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        current_token  =  tokens . next_token ( ) . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            track_end_placement_tokens . append ( current_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 20:00:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            current_token  =  tokens . next_token ( ) . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 13:50:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 20:00:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parsed_start_value  =  TRY ( parse_grid_track_placement ( track_start_placement_tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 13:50:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parsed_start_value  & &  track_end_placement_tokens . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  GridTrackPlacementShorthandStyleValue : : create ( parsed_start_value . release_nonnull ( ) - > as_grid_track_placement ( ) . grid_track_placement ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 20:00:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parsed_end_value  =  TRY ( parse_grid_track_placement ( track_end_placement_tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-10-01 13:50:11 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parsed_start_value  & &  parsed_end_value ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  GridTrackPlacementShorthandStyleValue : : create ( parsed_start_value . release_nonnull ( ) - > as_grid_track_placement ( ) ,  parsed_end_value . release_nonnull ( ) - > as_grid_track_placement ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 20:00:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 20:00:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-29 19:32:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-grid-2/#explicit-grid-shorthand
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								// 7.4. Explicit Grid Shorthand: the grid-template property
  
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_grid_track_size_list_shorthand_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2023-04-29 19:32:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The grid-template property is a shorthand for setting grid-template-columns, grid-template-rows,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // and grid-template-areas in a single declaration. It has several distinct syntax forms:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // none
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    - Sets all three properties to their initial values (none).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <'grid-template-rows'> / <'grid-template-columns'>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    - Sets grid-template-rows and grid-template-columns to the specified values, respectively, and sets grid-template-areas to none.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // [ <line-names>? <string> <track-size>? <line-names>? ]+ [ / <explicit-track-list> ]?
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    - Sets grid-template-areas to the strings listed.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    - Sets grid-template-rows to the <track-size>s following each string (filling in auto for any missing sizes),
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //      and splicing in the named lines defined before/after each size.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    - Sets grid-template-columns to the track listing specified after the slash (or none, if not specified).
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  template_rows_tokens ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  template_columns_tokens ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  template_area_tokens ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    int  forward_slash_index  =  - 1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( size_t  x  =  0 ;  x  <  component_values . size ( ) ;  x + + )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( component_values [ x ] . is_delim ( ' / ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-29 19:32:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            forward_slash_index  =  x ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( size_t  x  =  0 ;  x  <  ( forward_slash_index  >  - 1  ?  forward_slash_index  :  component_values . size ( ) ) ;  x + + )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( component_values [ x ] . is_token ( )  & &  component_values [ x ] . token ( ) . is ( Token : : Type : : String ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            template_area_tokens . append ( component_values [ x ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            template_rows_tokens . append ( component_values [ x ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( forward_slash_index  >  - 1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( size_t  x  =  forward_slash_index  +  1 ;  x  <  component_values . size ( ) ;  x + + ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            template_columns_tokens . append ( component_values [ x ] ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parsed_template_areas_values  =  TRY ( parse_grid_template_areas_value ( template_area_tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parsed_template_rows_values  =  TRY ( parse_grid_track_size_list ( template_rows_tokens ,  true ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parsed_template_columns_values  =  TRY ( parse_grid_track_size_list ( template_columns_tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-29 19:32:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  GridTrackSizeListShorthandStyleValue : : create ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        parsed_template_areas_values . release_nonnull ( ) - > as_grid_template_area ( ) , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        parsed_template_rows_values . release_nonnull ( ) - > as_grid_track_size_list ( ) , 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        parsed_template_columns_values . release_nonnull ( ) - > as_grid_track_size_list ( ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-29 19:32:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_grid_area_shorthand_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2023-01-16 19:02:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  tokens  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Token  current_token ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parse_placement_tokens  =  [ & ] ( Vector < ComponentValue > &  placement_tokens ,  bool  check_for_delimiter  =  true )  - >  void  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        current_token  =  tokens . next_token ( ) . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( check_for_delimiter  & &  current_token . is ( Token : : Type : : Delim )  & &  current_token . delim ( )  = =  " / " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            placement_tokens . append ( current_token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            current_token  =  tokens . next_token ( ) . token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  row_start_placement_tokens ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    parse_placement_tokens ( row_start_placement_tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  column_start_placement_tokens ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        parse_placement_tokens ( column_start_placement_tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  row_end_placement_tokens ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        parse_placement_tokens ( row_end_placement_tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  column_end_placement_tokens ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        parse_placement_tokens ( column_end_placement_tokens ,  false ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://www.w3.org/TR/css-grid-2/#placement-shorthands
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // The grid-area property is a shorthand for grid-row-start, grid-column-start, grid-row-end and
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // grid-column-end.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  row_start_style_value  =  TRY ( parse_grid_track_placement ( row_start_placement_tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  column_start_style_value  =  TRY ( parse_grid_track_placement ( column_start_placement_tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  row_end_style_value  =  TRY ( parse_grid_track_placement ( row_end_placement_tokens ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  column_end_style_value  =  TRY ( parse_grid_track_placement ( column_end_placement_tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 19:02:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // If four <grid-line> values are specified, grid-row-start is set to the first value, grid-column-start
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // is set to the second value, grid-row-end is set to the third value, and grid-column-end is set to the
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // fourth value.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  row_start  =  GridTrackPlacement : : make_auto ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  column_start  =  GridTrackPlacement : : make_auto ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  row_end  =  GridTrackPlacement : : make_auto ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  column_end  =  GridTrackPlacement : : make_auto ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( row_start_style_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        row_start  =  row_start_style_value . release_nonnull ( ) - > as_grid_track_placement ( ) . grid_track_placement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // When grid-column-start is omitted, if grid-row-start is a <custom-ident>, all four longhands are set to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // that value. Otherwise, it is set to auto.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( column_start_style_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        column_start  =  column_start_style_value . release_nonnull ( ) - > as_grid_track_placement ( ) . grid_track_placement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        column_start  =  row_start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // When grid-row-end is omitted, if grid-row-start is a <custom-ident>, grid-row-end is set to that
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <custom-ident>; otherwise, it is set to auto.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( row_end_style_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        row_end  =  row_end_style_value . release_nonnull ( ) - > as_grid_track_placement ( ) . grid_track_placement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        row_end  =  column_start ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // When grid-column-end is omitted, if grid-column-start is a <custom-ident>, grid-column-end is set to
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // that <custom-ident>; otherwise, it is set to auto.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( column_end_style_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        column_end  =  column_end_style_value . release_nonnull ( ) - > as_grid_track_placement ( ) . grid_track_placement ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        column_end  =  row_end ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  GridAreaShorthandStyleValue : : create ( row_start ,  column_start ,  row_end ,  column_end ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 19:02:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 02:58:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_grid_shorthand_value ( Vector < ComponentValue >  const &  component_value )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <'grid-template'> |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: <'grid-template-rows'> / [ auto-flow && dense? ] <'grid-auto-columns'>? |
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: [ auto-flow && dense? ] <'grid-auto-rows'>? / <'grid-template-columns'>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  parse_grid_track_size_list_shorthand_value ( component_value ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_grid_template_areas_value ( Vector < ComponentValue >  const &  component_values )  
						 
					
						
							
								
									
										
										
										
											2023-01-16 18:17:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Vector < String > >  grid_area_rows ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  component_value  :  component_values )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Vector < String >  grid_area_columns ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( component_value . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const  parts  =  TRY ( TRY ( String : : from_utf8 ( component_value . token ( ) . string ( ) ) ) . split ( '   ' ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 18:17:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto &  part  :  parts )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                grid_area_columns . append ( part ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        grid_area_rows . append ( move ( grid_area_columns ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  GridTemplateAreaStyleValue : : create ( grid_area_rows ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 18:17:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 03:56:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  block_contains_var_or_attr ( Block  const &  block ) ;  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								static  bool  function_contains_var_or_attr ( Function  const &  function )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( function . name ( ) . equals_ignoring_ascii_case ( " var " sv )  | |  function . name ( ) . equals_ignoring_ascii_case ( " attr " sv ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  token  :  function . values ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is_function ( )  & &  function_contains_var_or_attr ( token . function ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is_block ( )  & &  block_contains_var_or_attr ( token . block ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  block_contains_var_or_attr ( Block  const &  block )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto  const &  token  :  block . values ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is_function ( )  & &  function_contains_var_or_attr ( token . function ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is_block ( )  & &  block_contains_var_or_attr ( token . block ( ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-07 22:48:11 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2023-05-26 03:56:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Parser : : ParseErrorOr < NonnullRefPtr < StyleValue > >  Parser : : parse_css_value ( PropertyID  property_id ,  TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-07-14 16:20:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: This is a hack. Until we can reasonably combine the error types, just log the error
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //        and return ParseError::InternalError if we get an AK::Error result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								# define FIXME_TRY(expression)                                                                      \ 
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    ( {                                                                                              \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        /* Ignore -Wshadow to allow nesting the macro. */                                           \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        AK_IGNORE_DIAGNOSTIC ( " -Wshadow " ,                                                            \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto & &  _temporary_result  =  ( expression ) ) ;                                               \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( _temporary_result . is_error ( ) )  [[unlikely]]  {                                            \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln ( " System error when parsing style value: {} " ,  _temporary_result . release_error ( ) ) ;  \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  ParseError : : InternalError ;                                                       \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }                                                                                           \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        _temporary_result . release_value ( ) ;                                                          \
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-09-11 20:39:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    m_context . set_current_property_id ( property_id ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < ComponentValue >  component_values ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    bool  contains_var_or_attr  =  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-06 13:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    bool  const  property_accepts_custom_ident  =  property_accepts_type ( property_id ,  ValueType : : CustomIdent ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-14 16:20:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( tokens . has_next_token ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  token  =  tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-14 16:20:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( token . is ( Token : : Type : : Semicolon ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            tokens . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-12-03 12:32:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( property_id  ! =  PropertyID : : Custom )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( token . is ( Token : : Type : : Whitespace ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-14 16:20:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-06 13:05:48 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! property_accepts_custom_ident  & &  token . is ( Token : : Type : : Ident )  & &  has_ignored_vendor_prefix ( token . token ( ) . ident ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  ParseError : : IncludesIgnoredVendorPrefix ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-03 12:32:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! contains_var_or_attr )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 03:56:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( token . is_function ( )  & &  function_contains_var_or_attr ( token . function ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                contains_var_or_attr  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 03:56:02 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            else  if  ( token . is_block ( )  & &  block_contains_var_or_attr ( token . block ( ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                contains_var_or_attr  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-03 12:32:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-14 16:20:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        component_values . append ( token ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-29 23:33:50 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( property_id  = =  PropertyID : : Custom  | |  contains_var_or_attr ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  FIXME_TRY ( UnresolvedStyleValue : : create ( move ( component_values ) ,  contains_var_or_attr ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-03 12:32:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-14 16:20:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-14 16:20:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-08-19 15:45:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_builtin_value ( component_values . first ( ) ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-19 15:45:15 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:12:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Special-case property handling
 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    switch  ( property_id )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-08 15:25:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : AspectRatio : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_aspect_ratio_value ( component_values ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BackdropFilter : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_filter_value_list_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-15 08:31:17 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 14:56:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : Background : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_background_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BackgroundAttachment : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BackgroundClip : 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 16:20:30 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BackgroundImage : 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-08 17:19:55 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BackgroundOrigin : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:31:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_simple_comma_separated_value_list ( property_id ,  component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BackgroundPosition : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_comma_separated_value_list ( component_values ,  [ this ] ( auto &  tokens )  {  return  parse_single_background_position_value ( tokens ) ;  } ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-10-31 16:02:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BackgroundPositionX : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BackgroundPositionY : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_comma_separated_value_list ( component_values ,  [ this ,  property_id ] ( auto &  tokens )  {  return  parse_single_background_position_x_or_y_value ( tokens ,  property_id ) ;  } ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-03 00:04:00 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-10 10:21:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BackgroundRepeat : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_comma_separated_value_list ( component_values ,  [ this ] ( auto &  tokens )  {  return  parse_single_background_repeat_value ( tokens ) ;  } ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 13:44:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BackgroundSize : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_comma_separated_value_list ( component_values ,  [ this ] ( auto &  tokens )  {  return  parse_single_background_size_value ( tokens ) ;  } ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-11-05 13:44:37 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 21:11:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : Border : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BorderBottom : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BorderLeft : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BorderRight : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BorderTop : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_border_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BorderTopLeftRadius : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BorderTopRightRadius : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BorderBottomRightRadius : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BorderBottomLeftRadius : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_border_radius_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-06 16:55:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BorderRadius : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_border_radius_shorthand_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : BoxShadow : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_shadow_value ( component_values ,  AllowInsetKeyword : : Yes ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : Content : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_content_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-23 19:56:25 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : Display : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_display_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-26 21:05:38 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 17:48:08 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : Flex : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_flex_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-05 17:19:29 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : FlexFlow : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_flex_flow_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : Font : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_font_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : FontFamily :  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  tokens_without_whitespace  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_font_family_value ( tokens_without_whitespace ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-24 16:09:38 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 20:00:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridColumn : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_track_placement_shorthand_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 20:00:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 19:02:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridArea : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_area_shorthand_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 19:02:39 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 18:17:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridTemplateAreas : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_template_areas_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-01-16 18:17:05 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridColumnEnd : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_track_placement ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridColumnStart : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_track_placement ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 20:00:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridRow : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_track_placement_shorthand_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 20:00:16 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridRowEnd : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_track_placement ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridRowStart : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_track_placement ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:58:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 02:58:19 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : Grid : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_shorthand_value ( component_values ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-29 19:32:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridTemplate : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_track_size_list_shorthand_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-29 19:32:56 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:49:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridTemplateColumns : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_track_size_list ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:49:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridTemplateRows : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_track_size_list ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:49:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-21 18:08:41 +03:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridAutoColumns : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_auto_track_sizes ( component_values ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : GridAutoRows : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_grid_auto_track_sizes ( component_values ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-08-23 19:49:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 15:56:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : ListStyle : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_list_style_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-09 14:54:40 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : Overflow : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_overflow_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-29 16:34:53 -04:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : PlaceContent : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_place_content_value ( component_values ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-04 12:34:14 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : TextDecoration : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_text_decoration_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : TextDecorationLine :  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:35:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        TokenStream  value_tokens  {  component_values  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  parsed_value  =  FIXME_TRY ( parse_text_decoration_line_value ( value_tokens ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:35:25 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( parsed_value  & &  ! value_tokens . has_next_token ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-14 16:22:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 21:16:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : TextShadow : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_shadow_value ( component_values ,  AllowInsetKeyword : : No ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-23 21:16:36 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 17:20:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : Transform : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_transform_value ( component_values ) ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-18 17:20:00 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 19:11:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    case  PropertyID : : TransformOrigin : 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_transform_origin_value ( component_values ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError  : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-03 11:37:24 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    default : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 14:12:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:31:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // If there's only 1 ComponentValue, we can only produce a single StyleValue.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( component_values . size ( )  = =  1 )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:31:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  stream  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  parsed_value  =  FIXME_TRY ( parse_css_value_for_property ( property_id ,  stream ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  parsed_value . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 11:04:16 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 19:44:35 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-14 16:20:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:31:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // Multiple ComponentValues will usually produce multiple StyleValues, so make a StyleValueList.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 23:16:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        StyleValueVector  parsed_values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  stream  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        while  ( auto  parsed_value  =  FIXME_TRY ( parse_css_value_for_property ( property_id ,  stream ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            FIXME_TRY ( parsed_values . try_append ( parsed_value . release_nonnull ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! stream . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // Some types (such as <ratio>) can be made from multiple ComponentValues, so if we only made 1 StyleValue, return it directly.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( parsed_values . size ( )  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  * parsed_values . take_first ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! parsed_values . is_empty ( )  & &  parsed_values . size ( )  < =  property_maximum_value_count ( property_id ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  FIXME_TRY ( StyleValueList : : create ( move ( parsed_values ) ,  StyleValueList : : Separator : : Space ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // We have multiple values, but the property claims to accept only a single one, check if it's a shorthand property.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  unassigned_properties  =  longhands_for_shorthand ( property_id ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( unassigned_properties . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:31:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  stream  =  TokenStream  {  component_values  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 23:16:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    HashMap < UnderlyingType < PropertyID > ,  Vector < ValueComparingNonnullRefPtr < StyleValue  const > > >  assigned_values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( stream . has_next_token ( )  & &  ! unassigned_properties . is_empty ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  property_and_value  =  parse_css_value_for_properties ( unassigned_properties ,  stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! property_and_value . is_error ( )  & &  property_and_value . value ( ) . style_value )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  property  =  property_and_value . value ( ) . property ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  value  =  property_and_value . release_value ( ) . style_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  values  =  assigned_values . ensure ( to_underlying ( property ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( values . size ( )  +  1  = =  property_maximum_value_count ( property ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // We're done with this property, move on to the next one.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                unassigned_properties . remove_first_matching ( [ & ] ( auto &  unassigned_property )  {  return  unassigned_property  = =  property ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            values . append ( value . release_nonnull ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // No property matched, so we're done.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln ( " No property (from {} properties) matched {} " ,  unassigned_properties . size ( ) ,  stream . peek_token ( ) . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  id  :  unassigned_properties ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln ( "     {} " ,  string_from_property_id ( id ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        break ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-08-14 14:01:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 23:16:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  property  :  unassigned_properties ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        assigned_values . ensure ( to_underlying ( property ) ) . append ( FIXME_TRY ( property_initial_value ( m_context . realm ( ) ,  property ) ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:31:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 23:16:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    stream . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( stream . has_next_token ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  ParseError : : SyntaxError ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:31:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 23:16:43 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < PropertyID >  longhand_properties ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    longhand_properties . ensure_capacity ( assigned_values . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  it  :  assigned_values ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        longhand_properties . unchecked_append ( static_cast < PropertyID > ( it . key ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    StyleValueVector  longhand_values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    longhand_values . ensure_capacity ( assigned_values . size ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  it  :  assigned_values )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( it . value . size ( )  = =  1 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            longhand_values . unchecked_append ( it . value . take_first ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            longhand_values . unchecked_append ( FIXME_TRY ( StyleValueList : : create ( move ( it . value ) ,  StyleValueList : : Separator : : Space ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  {  FIXME_TRY ( CompositeStyleValue : : create ( move ( longhand_properties ) ,  move ( longhand_values ) ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								# undef FIXME_TRY 
  
						 
					
						
							
								
									
										
										
										
											2021-07-14 16:20:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_css_value_for_property ( PropertyID  property_id ,  TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  result  =  parse_css_value_for_properties ( {  & property_id ,  1  } ,  tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( result . is_error ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  result . release_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  result . value ( ) . style_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < Parser : : PropertyAndValue >  Parser : : parse_css_value_for_properties ( ReadonlySpan < PropertyID >  property_ids ,  TokenStream < ComponentValue > &  tokens )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  any_property_accepts_type  =  [ ] ( ReadonlySpan < PropertyID >  property_ids ,  ValueType  value_type )  - >  Optional < PropertyID >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  property  :  property_ids )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( property_accepts_type ( property ,  value_type ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  property ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 16:29:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  any_property_accepts_type_percentage  =  [ ] ( ReadonlySpan < PropertyID >  property_ids ,  ValueType  value_type )  - >  Optional < PropertyID >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  property  :  property_ids )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( property_accepts_type ( property ,  value_type )  & &  property_accepts_type ( property ,  ValueType : : Percentage ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  property ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  any_property_accepts_identifier  =  [ ] ( ReadonlySpan < PropertyID >  property_ids ,  ValueID  identifier )  - >  Optional < PropertyID >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  const &  property  :  property_ids )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( property_accepts_identifier ( property ,  identifier ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  property ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto &  peek_token  =  tokens . peek_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-06 16:54:15 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : EasingFunction ) ;  property . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_easing_function  =  TRY ( parse_easing_value ( tokens ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  PropertyAndValue  {  * property ,  maybe_easing_function  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( peek_token . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: We do not try to parse "CSS-wide keywords" here. https://www.w3.org/TR/css-values-4/#common-keywords
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       These are only valid on their own, and so should be parsed directly in `parse_css_value()`.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  value_id_from_string ( peek_token . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  property  =  any_property_accepts_identifier ( property_ids ,  ident . value ( ) ) ;  property . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  PropertyAndValue  {  * property ,  TRY ( IdentifierStyleValue : : create ( ident . value ( ) ) )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-25 12:43:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // Custom idents
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : CustomIdent ) ;  property . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  PropertyAndValue  {  * property ,  TRY ( CustomIdentStyleValue : : create ( TRY ( FlyString : : from_utf8 ( peek_token . token ( ) . ident ( ) ) ) ) )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Color ) ;  property . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_color  =  TRY ( parse_color_value ( peek_token ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  PropertyAndValue  {  * property ,  maybe_color  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Image ) ;  property . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_image  =  TRY ( parse_image_value ( peek_token ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  PropertyAndValue  {  * property ,  maybe_image  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 15:42:43 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Ratio ) ;  property . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_ratio  =  TRY ( parse_ratio_value ( tokens ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  PropertyAndValue  {  * property ,  maybe_ratio  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  property_accepting_integer  =  any_property_accepts_type ( property_ids ,  ValueType : : Integer ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  property_accepting_number  =  any_property_accepts_type ( property_ids ,  ValueType : : Number ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  property_accepts_numeric  =  property_accepting_integer . has_value ( )  | |  property_accepting_number . has_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( peek_token . is ( Token : : Type : : Number )  & &  property_accepts_numeric )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:01:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( property_accepting_integer . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  integer  =  TRY ( parse_integer_value ( tokens ) ) ;  integer  & &  property_accepts_integer ( * property_accepting_integer ,  integer - > as_integer ( ) . integer ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:01:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  PropertyAndValue  {  * property_accepting_integer ,  integer  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:01:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( property_accepting_number . has_value ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( auto  number  =  TRY ( parse_number_value ( tokens ) ) ;  number  & &  property_accepts_number ( * property_accepting_number ,  number - > as_number ( ) . number ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:01:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                return  PropertyAndValue  {  * property_accepting_number ,  number  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-01 17:01:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( peek_token . is ( Token : : Type : : Percentage ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  percentage  =  Percentage ( peek_token . token ( ) . percentage ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Percentage ) ;  property . has_value ( )  & &  property_accepts_percentage ( * property ,  percentage ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  PropertyAndValue  {  * property ,  TRY ( PercentageStyleValue : : create ( percentage ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Rect ) ;  property . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_rect  =  TRY ( parse_rect_value ( peek_token ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  PropertyAndValue  {  * property ,  maybe_rect  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( peek_token . is ( Token : : Type : : String ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : String ) ;  property . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  PropertyAndValue  {  * property ,  TRY ( StringStyleValue : : create ( TRY ( String : : from_utf8 ( tokens . next_token ( ) . token ( ) . string ( ) ) ) ) )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Url ) ;  property . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  url  =  TRY ( parse_url_value ( peek_token ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  PropertyAndValue  {  * property ,  url  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  property_accepts_dimension  =  any_property_accepts_type ( property_ids ,  ValueType : : Angle ) . has_value ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  any_property_accepts_type ( property_ids ,  ValueType : : Length ) . has_value ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  any_property_accepts_type ( property_ids ,  ValueType : : Percentage ) . has_value ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  any_property_accepts_type ( property_ids ,  ValueType : : Resolution ) . has_value ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  any_property_accepts_type ( property_ids ,  ValueType : : Time ) . has_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( property_accepts_dimension )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  transaction  =  tokens . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_dimension  =  parse_dimension ( peek_token ) ;  maybe_dimension . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  dimension  =  maybe_dimension . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( dimension . is_angle ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  angle  =  dimension . angle ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Angle ) ;  property . has_value ( )  & &  property_accepts_angle ( * property ,  angle ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  TRY ( AngleStyleValue : : create ( angle ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( dimension . is_frequency ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  frequency  =  dimension . frequency ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Frequency ) ;  property . has_value ( )  & &  property_accepts_frequency ( * property ,  frequency ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  TRY ( FrequencyStyleValue : : create ( frequency ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( dimension . is_length ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  length  =  dimension . length ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Length ) ;  property . has_value ( )  & &  property_accepts_length ( * property ,  length ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  TRY ( LengthStyleValue : : create ( length ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( dimension . is_resolution ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  resolution  =  dimension . resolution ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Resolution ) ;  property . has_value ( )  & &  property_accepts_resolution ( * property ,  resolution ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  TRY ( ResolutionStyleValue : : create ( resolution ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( dimension . is_time ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                auto  time  =  dimension . time ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Time ) ;  property . has_value ( )  & &  property_accepts_time ( * property ,  time ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 15:15:45 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  TRY ( TimeStyleValue : : create ( time ) )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 20:28:33 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // In order to not end up parsing `calc()` and other math expressions multiple times,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // we parse it once, and then see if its resolved type matches what the property accepts.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( peek_token . is_function ( )  & &  ( property_accepts_dimension  | |  property_accepts_numeric ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  maybe_dynamic  =  TRY ( parse_dynamic_value ( peek_token ) ) ;  maybe_dynamic  & &  maybe_dynamic - > is_calculated ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            ( void ) tokens . next_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  calculated  =  maybe_dynamic - > as_calculated ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 16:29:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( calculated . resolves_to_angle_percentage ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type_percentage ( property_ids ,  ValueType : : Angle ) ;  property . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  calculated  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( calculated . resolves_to_angle ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Angle ) ;  property . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  calculated  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 16:29:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( calculated . resolves_to_frequency_percentage ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type_percentage ( property_ids ,  ValueType : : Frequency ) ;  property . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  calculated  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( calculated . resolves_to_frequency ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Frequency ) ;  property . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  calculated  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 16:29:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( calculated . resolves_to_number_percentage ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type_percentage ( property_ids ,  ValueType : : Number ) ;  property . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  calculated  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( calculated . resolves_to_number ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-27 22:56:07 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( property_accepts_numeric )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    auto  property_or_resolved  =  property_accepting_integer . value_or_lazy_evaluated ( [ property_accepting_number ] ( )  {  return  property_accepting_number . value ( ) ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  property_or_resolved ,  calculated  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 16:29:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( calculated . resolves_to_length_percentage ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type_percentage ( property_ids ,  ValueType : : Length ) ;  property . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  calculated  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( calculated . resolves_to_length ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Length ) ;  property . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  calculated  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 16:29:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( calculated . resolves_to_time_percentage ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type_percentage ( property_ids ,  ValueType : : Time ) ;  property . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  calculated  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 16:29:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( calculated . resolves_to_time ( ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Time ) ;  property . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  calculated  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-30 16:29:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            }  else  if  ( calculated . resolves_to_percentage ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Percentage ) ;  property . has_value ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  PropertyAndValue  {  * property ,  calculated  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-06-15 16:37:36 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( auto  property  =  any_property_accepts_type ( property_ids ,  ValueType : : Paint ) ;  property . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  value  =  TRY ( parse_paint_value ( tokens ) ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  PropertyAndValue  {  * property ,  value . release_nonnull ( )  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-17 17:23:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  PropertyAndValue  {  property_ids . first ( ) ,  nullptr  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Optional < Selector : : SimpleSelector : : ANPlusBPattern >  Parser : : parse_a_n_plus_b_pattern ( TokenStream < ComponentValue > &  values )  
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  transaction  =  values . begin_transaction ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  syntax_error  =  [ & ] ( )  - >  Optional < Selector : : SimpleSelector : : ANPlusBPattern >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  constexpr  ( CSS_PARSER_DEBUG )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-02-05 16:16:18 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            dbgln_if ( CSS_PARSER_DEBUG ,  " Invalid An+B value: " ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            values . dump_all_tokens ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_n  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  value . is ( Token : : Type : : Ident )  & &  value . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " n " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_ndash  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  value . is ( Token : : Type : : Ident )  & &  value . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " n- " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_dashn  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  value . is ( Token : : Type : : Ident )  & &  value . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " -n " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_dashndash  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  value . is ( Token : : Type : : Ident )  & &  value . token ( ) . ident ( ) . equals_ignoring_ascii_case ( " -n- " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_sign  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  value . is ( Token : : Type : : Delim )  & &  ( value . token ( ) . delim ( )  = =  ' + '  | |  value . token ( ) . delim ( )  = =  ' - ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_n_dimension  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value . is ( Token : : Type : : Dimension ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 21:01:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value . token ( ) . number ( ) . is_integer ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value . token ( ) . dimension_unit ( ) . equals_ignoring_ascii_case ( " n " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_ndash_dimension  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value . is ( Token : : Type : : Dimension ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 21:01:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value . token ( ) . number ( ) . is_integer ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value . token ( ) . dimension_unit ( ) . equals_ignoring_ascii_case ( " n- " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_ndashdigit_dimension  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value . is ( Token : : Type : : Dimension ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 21:01:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value . token ( ) . number ( ) . is_integer ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  dimension_unit  =  value . token ( ) . dimension_unit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! dimension_unit . starts_with ( " n- " sv ,  CaseSensitivity : : CaseInsensitive ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( size_t  i  =  2 ;  i  <  dimension_unit . length ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! is_ascii_digit ( dimension_unit [ i ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_ndashdigit_ident  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  value . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! ident . starts_with ( " n- " sv ,  CaseSensitivity : : CaseInsensitive ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( size_t  i  =  2 ;  i  <  ident . length ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! is_ascii_digit ( ident [ i ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_dashndashdigit_ident  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! value . is ( Token : : Type : : Ident ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  value . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! ident . starts_with ( " -n- " sv ,  CaseSensitivity : : CaseInsensitive ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 00:25:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . length ( )  = =  3 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( size_t  i  =  3 ;  i  <  ident . length ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! is_ascii_digit ( ident [ i ] ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_integer  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 21:01:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  value . is ( Token : : Type : : Number )  & &  value . token ( ) . number ( ) . is_integer ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_signed_integer  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 21:01:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  value . is ( Token : : Type : : Number )  & &  value . token ( ) . number ( ) . is_integer_with_explicit_sign ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-31 11:43:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  is_signless_integer  =  [ ] ( ComponentValue  const &  value )  - >  bool  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-21 21:01:27 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  value . is ( Token : : Type : : Number )  & &  ! value . token ( ) . number ( ) . is_integer_with_explicit_sign ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // https://www.w3.org/TR/css-syntax-3/#the-anb-type
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // Unfortunately these can't be in the same order as in the spec.
 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    values . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  first_value  =  values . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // odd | even
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( first_value . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  ident  =  first_value . token ( ) . ident ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " odd " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector : : ANPlusBPattern  {  2 ,  1  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ident . equals_ignoring_ascii_case ( " even " sv ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector : : ANPlusBPattern  {  2 ,  0  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // <integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_integer ( first_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        int  b  =  first_value . token ( ) . to_integer ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : SimpleSelector : : ANPlusBPattern  {  0 ,  b  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <n-dimension>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <n-dimension> <signed-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <n-dimension> ['+' | '-'] <signless-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_n_dimension ( first_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        int  a  =  first_value . token ( ) . dimension_value_int ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-24 16:38:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        values . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // <n-dimension> <signed-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_signed_integer ( values . peek_token ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            int  b  =  values . next_token ( ) . token ( ) . to_integer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector : : ANPlusBPattern  {  a ,  b  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <n-dimension> ['+' | '-'] <signless-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  child_transaction  =  transaction . create_child ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  second_value  =  values . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            values . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  third_value  =  values . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is_sign ( second_value )  & &  is_signless_integer ( third_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                int  b  =  third_value . token ( ) . to_integer ( )  *  ( second_value . is_delim ( ' + ' )  ?  1  :  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                child_transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Selector : : SimpleSelector : : ANPlusBPattern  {  a ,  b  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // <n-dimension>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : SimpleSelector : : ANPlusBPattern  {  a ,  0  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <ndash-dimension> <signless-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_ndash_dimension ( first_value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        values . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  second_value  =  values . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_signless_integer ( second_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            int  a  =  first_value . token ( ) . dimension_value_int ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-07 23:46:19 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            int  b  =  - second_value . token ( ) . to_integer ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:03:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector : : ANPlusBPattern  {  a ,  b  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  syntax_error ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // <ndashdigit-dimension>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_ndashdigit_dimension ( first_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  dimension  =  first_value . token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        int  a  =  dimension . dimension_value_int ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_b  =  dimension . dimension_unit ( ) . substring_view ( 1 ) . to_int ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( maybe_b . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector : : ANPlusBPattern  {  a ,  maybe_b . value ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  syntax_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // <dashndashdigit-ident>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_dashndashdigit_ident ( first_value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_b  =  first_value . token ( ) . ident ( ) . substring_view ( 2 ) . to_int ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( maybe_b . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector : : ANPlusBPattern  {  - 1 ,  maybe_b . value ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  syntax_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -n <signed-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -n ['+' | '-'] <signless-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_dashn ( first_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-24 16:38:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        values . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // -n <signed-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_signed_integer ( values . peek_token ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            int  b  =  values . next_token ( ) . token ( ) . to_integer ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector : : ANPlusBPattern  {  - 1 ,  b  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // -n ['+' | '-'] <signless-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  child_transaction  =  transaction . create_child ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  second_value  =  values . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            values . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  third_value  =  values . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is_sign ( second_value )  & &  is_signless_integer ( third_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                int  b  =  third_value . token ( ) . to_integer ( )  *  ( second_value . is_delim ( ' + ' )  ?  1  :  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                child_transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Selector : : SimpleSelector : : ANPlusBPattern  {  - 1 ,  b  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // -n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : SimpleSelector : : ANPlusBPattern  {  - 1 ,  0  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // -n- <signless-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_dashndash ( first_value ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        values . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  second_value  =  values . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_signless_integer ( second_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            int  b  =  - second_value . token ( ) . to_integer ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector : : ANPlusBPattern  {  - 1 ,  b  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  syntax_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // All that's left now are these:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // '+'?† n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // '+'?† n <signed-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // '+'?† n ['+' | '-'] <signless-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // '+'?† n- <signless-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // '+'?† <ndashdigit-ident>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // In all of these cases, the + is optional, and has no effect.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // So, we just skip the +, and carry on.
 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! first_value . is_delim ( ' + ' ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        values . reconsume_current_input_token ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // We do *not* skip whitespace here.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  const &  first_after_plus  =  values . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // '+'?† n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // '+'?† n <signed-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // '+'?† n ['+' | '-'] <signless-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_n ( first_after_plus ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-24 16:38:34 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        values . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // '+'?† n <signed-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_signed_integer ( values . peek_token ( ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            int  b  =  values . next_token ( ) . token ( ) . to_integer ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-05-08 01:03:32 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector : : ANPlusBPattern  {  1 ,  b  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // '+'?† n ['+' | '-'] <signless-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  child_transaction  =  transaction . create_child ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  second_value  =  values . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            values . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  const &  third_value  =  values . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( is_sign ( second_value )  & &  is_signless_integer ( third_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-06 14:28:42 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                int  b  =  third_value . token ( ) . to_integer ( )  *  ( second_value . is_delim ( ' + ' )  ?  1  :  - 1 ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                child_transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  Selector : : SimpleSelector : : ANPlusBPattern  {  1 ,  b  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // '+'?† n
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        transaction . commit ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  Selector : : SimpleSelector : : ANPlusBPattern  {  1 ,  0  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // '+'?† n- <signless-integer>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_ndash ( first_after_plus ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        values . skip_whitespace ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-09-10 12:50:27 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto  const &  second_value  =  values . next_token ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( is_signless_integer ( second_value ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            int  b  =  - second_value . token ( ) . to_integer ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector : : ANPlusBPattern  {  1 ,  b  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  syntax_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // '+'?† <ndashdigit-ident>
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_ndashdigit_ident ( first_after_plus ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  maybe_b  =  first_after_plus . token ( ) . ident ( ) . substring_view ( 1 ) . to_int ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( maybe_b . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            transaction . commit ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:18:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  Selector : : SimpleSelector : : ANPlusBPattern  {  1 ,  maybe_b . value ( )  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-27 12:54:52 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  syntax_error ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-07-24 21:22:44 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  syntax_error ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-08 13:44:01 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								class  UnparsedCalculationNode  final  :  public  CalculationNode  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								public :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    static  ErrorOr < NonnullOwnPtr < UnparsedCalculationNode > >  create ( ComponentValue  component_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  adopt_nonnull_own_or_enomem ( new  ( nothrow )  UnparsedCalculationNode ( move ( component_value ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    virtual  ~ UnparsedCalculationNode ( )  =  default ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    ComponentValue &  component_value ( )  {  return  m_component_value ;  } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    virtual  ErrorOr < String >  to_string ( )  const  override  {  VERIFY_NOT_REACHED ( ) ;  } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    virtual  Optional < CalculatedStyleValue : : ResolvedType >  resolved_type ( )  const  override  {  VERIFY_NOT_REACHED ( ) ;  } 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-05 19:58:13 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    virtual  Optional < CSSNumericType >  determine_type ( Web : : CSS : : PropertyID )  const  override  {  VERIFY_NOT_REACHED ( ) ;  } 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    virtual  bool  contains_percentage ( )  const  override  {  VERIFY_NOT_REACHED ( ) ;  } 
							 
						 
					
						
							
								
									
										
										
										
											2023-06-02 12:39:39 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    virtual  CalculatedStyleValue : : CalculationResult  resolve ( Optional < Length : : ResolutionContext  const & > ,  CalculatedStyleValue : : PercentageBasis  const & )  const  override  {  VERIFY_NOT_REACHED ( ) ;  } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    virtual  ErrorOr < void >  dump ( StringBuilder &  builder ,  int  indent )  const  override 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  builder . try_appendff ( " {: >{}}UNPARSED({}) \n " ,  " " ,  indent ,  TRY ( m_component_value . to_debug_string ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								private :  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    UnparsedCalculationNode ( ComponentValue  component_value ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        :  CalculationNode ( Type : : Unparsed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        ,  m_component_value ( move ( component_value ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    ComponentValue  m_component_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								} ;  
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-07-09 21:04:16 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://html.spec.whatwg.org/multipage/images.html#parsing-a-sizes-attribute
  
						 
					
						
							
								
									
										
										
										
											2023-07-09 11:48:45 +03:30 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Length  Parser : : Parser : : parse_as_sizes_attribute ( )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < Length >  size ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // When asked to parse a sizes attribute from an element,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // parse a comma-separated list of component values from the value of the element's sizes attribute
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // (or the empty string, if the attribute is absent), and let unparsed sizes list be the result.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    auto  unparsed_sizes_list  =  parse_a_comma_separated_list_of_component_values ( m_token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    // For each unparsed size in unparsed sizes list:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  unparsed_size  :  unparsed_sizes_list )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. Remove all consecutive <whitespace-token>s from the end of unparsed size.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    If unparsed size is now empty, that is a parse error; continue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        while  ( ! unparsed_size . is_empty ( )  & &  unparsed_size . last ( ) . is_token ( )  & &  unparsed_size . last ( ) . token ( ) . is ( Token : : Type : : Whitespace ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            unparsed_size . take_last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( unparsed_size . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If the last component value in unparsed size is a valid non-negative <source-size-value>,
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    let size be its value and remove the component value from unparsed size.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    FIXME: Any CSS function other than the math functions is invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    Otherwise, there is a parse error; continue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  length  =  parse_length ( unparsed_size . last ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( length . has_value ( )  & &  length . value ( ) . raw_value ( )  > =  0 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            size  =  length . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            unparsed_size . take_last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 3. Remove all consecutive <whitespace-token>s from the end of unparsed size.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    If unparsed size is now empty, return size and exit this algorithm.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    If this was not the last item in unparsed sizes list, that is a parse error.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        while  ( ! unparsed_size . is_empty ( )  & &  unparsed_size . last ( ) . is_token ( )  & &  unparsed_size . last ( ) . token ( ) . is ( Token : : Type : : Whitespace ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            unparsed_size . take_last ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( unparsed_size . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  size . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 4. Parse the remaining component values in unparsed size as a <media-condition>.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    If it does not parse correctly, or it does parse correctly but the <media-condition> evaluates to false, continue.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TokenStream < ComponentValue >  token_stream  {  unparsed_size  } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  media_condition  =  parse_media_condition ( token_stream ,  MediaCondition : : AllowOr : : Yes ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( media_condition  & &  media_condition - > evaluate ( * m_context . window ( ) )  = =  MatchResult : : True )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  size . value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        }  else  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  Length ( 100 ,  Length : : Type : : Vw ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								// https://www.w3.org/TR/css-values-4/#parse-a-calculation
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < OwnPtr < CalculationNode > >  Parser : : parse_a_calculation ( Vector < ComponentValue >  const &  original_values )  
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 1. Discard any <whitespace-token>s from values.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
										 
							
							
								    // 2. An item in values is an “operator” if it’ ’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    struct  Operator  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        char  delim ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    using  Value  =  Variant < NonnullOwnPtr < CalculationNode > ,  Operator > ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Vector < Value >  values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    for  ( auto &  value  :  original_values )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value . is ( Token : : Type : : Whitespace ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value . is ( Token : : Type : : Delim ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( first_is_one_of ( value . token ( ) . delim ( ) ,  static_cast < u32 > ( ' + ' ) ,  static_cast < u32 > ( ' - ' ) ,  static_cast < u32 > ( ' * ' ) ,  static_cast < u32 > ( ' / ' ) ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                // NOTE: Sequential operators are invalid syntax.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( ! values . is_empty ( )  & &  values . last ( ) . has < Operator > ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                TRY ( values . try_append ( Operator  {  static_cast < char > ( value . token ( ) . delim ( ) )  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 21:24:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value . is ( Token : : Type : : Ident ) )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-07-08 16:55:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  maybe_constant  =  CalculationNode : : constant_type_from_string ( value . token ( ) . ident ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( maybe_constant . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                TRY ( values . try_append ( {  TRY ( ConstantCalculationNode : : create ( maybe_constant . value ( ) ) )  } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-26 21:24:31 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( value . is ( Token : : Type : : Number ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( values . try_append ( {  TRY ( NumericCalculationNode : : create ( value . token ( ) . number ( ) ) )  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( auto  dimension  =  parse_dimension ( value ) ;  dimension . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( dimension - > is_angle ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                TRY ( values . try_append ( {  TRY ( NumericCalculationNode : : create ( dimension - > angle ( ) ) )  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else  if  ( dimension - > is_frequency ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                TRY ( values . try_append ( {  TRY ( NumericCalculationNode : : create ( dimension - > frequency ( ) ) )  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else  if  ( dimension - > is_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                TRY ( values . try_append ( {  TRY ( NumericCalculationNode : : create ( dimension - > length ( ) ) )  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else  if  ( dimension - > is_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                TRY ( values . try_append ( {  TRY ( NumericCalculationNode : : create ( dimension - > percentage ( ) ) )  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            // FIXME: Resolutions, once calc() supports them.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else  if  ( dimension - > is_time ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                TRY ( values . try_append ( {  TRY ( NumericCalculationNode : : create ( dimension - > time ( ) ) )  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            else 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( values . try_append ( {  TRY ( UnparsedCalculationNode : : create ( value ) )  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // If we have no values, the syntax is invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( values . is_empty ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // NOTE: If the first or last value is an operator, the syntax is invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( values . first ( ) . has < Operator > ( )  | |  values . last ( ) . has < Operator > ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-31 15:10:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 3. Collect children into Product and Invert nodes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //    For every consecutive run of value items in values separated by "*" or "/" operators:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    while  ( true )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Optional < size_t >  first_product_operator  =  values . find_first_index_if ( [ ] ( auto  const &  item )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  item . template  has < Operator > ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                & &  first_is_one_of ( item . template  get < Operator > ( ) . delim ,  ' * ' ,  ' / ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! first_product_operator . has_value ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            break ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  start_of_run  =  first_product_operator . value ( )  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  end_of_run  =  first_product_operator . value ( )  +  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  i  =  start_of_run  +  1 ;  i  <  values . size ( ) ;  i  + =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  item  =  values [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! item . has < Operator > ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                end_of_run  =  i  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  delim  =  item . get < Operator > ( ) . delim ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! first_is_one_of ( delim ,  ' * ' ,  ' / ' ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                end_of_run  =  i  -  1 ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                break ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. For each "/" operator in the run, replace its right-hand value item rhs with an Invert node containing rhs as its child.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        Vector < NonnullOwnPtr < CalculationNode > >  run_values ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( run_values . try_append ( move ( values [ start_of_run ] . get < NonnullOwnPtr < CalculationNode > > ( ) ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  i  =  start_of_run  +  1 ;  i  < =  end_of_run ;  i  + =  2 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  operator_  =  values [ i ] . get < Operator > ( ) . delim ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  rhs  =  values [ i  +  1 ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( operator_  = =  ' / ' )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                TRY ( run_values . try_append ( TRY ( InvertCalculationNode : : create ( move ( rhs . get < NonnullOwnPtr < CalculationNode > > ( ) ) ) ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            VERIFY ( operator_  = =  ' * ' ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( run_values . try_append ( move ( rhs . get < NonnullOwnPtr < CalculationNode > > ( ) ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. Replace the entire run with a Product node containing the value items of the run as its children.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto  product_node  =  TRY ( ProductCalculationNode : : create ( move ( run_values ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        values . remove ( start_of_run ,  end_of_run  -  start_of_run  +  1 ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        TRY ( values . try_insert ( start_of_run ,  {  move ( product_node )  } ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 4. Collect children into Sum and Negate nodes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    Optional < NonnullOwnPtr < CalculationNode > >  single_value ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // 1. For each "-" operator item in values, replace its right-hand value item rhs with a Negate node containing rhs as its child.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        for  ( auto  i  =  0u ;  i  <  values . size ( ) ;  + + i )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  maybe_minus_operator  =  values [ i ] ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! maybe_minus_operator . has < Operator > ( )  | |  maybe_minus_operator . get < Operator > ( ) . delim  ! =  ' - ' ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                continue ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  rhs_index  =  + + i ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  rhs  =  values [ rhs_index ] ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            NonnullOwnPtr < CalculationNode >  negate_node  =  TRY ( NegateCalculationNode : : create ( move ( rhs . get < NonnullOwnPtr < CalculationNode > > ( ) ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            values . remove ( rhs_index ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            values . insert ( rhs_index ,  move ( negate_node ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If values has only one item, and it is a Product node or a parenthesized simple block, replace values with that item.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( values . size ( )  = =  1 )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( values . first ( ) . visit ( 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                [ & ] ( ComponentValue &  component_value )  - >  ErrorOr < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( component_value . is_block ( )  & &  component_value . block ( ) . is_paren ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        single_value  =  TRY ( UnparsedCalculationNode : : create ( component_value ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                [ & ] ( NonnullOwnPtr < CalculationNode > &  node )  - >  ErrorOr < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    if  ( node - > type ( )  = =  CalculationNode : : Type : : Product ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                        single_value  =  move ( node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                } , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                [ ] ( auto & )  - >  ErrorOr < void >  {  return  { } ;  } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //    Otherwise, replace values with a Sum node containing the value items of values as its children.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( ! single_value . has_value ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            values . remove_all_matching ( [ ] ( Value &  value )  {  return  value . has < Operator > ( ) ;  } ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            Vector < NonnullOwnPtr < CalculationNode > >  value_items ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            TRY ( value_items . try_ensure_capacity ( values . size ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            for  ( auto &  value  :  values )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                if  ( value . has < Operator > ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                    continue ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                value_items . unchecked_append ( move ( value . get < NonnullOwnPtr < CalculationNode > > ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            single_value  =  TRY ( SumCalculationNode : : create ( move ( value_items ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // 5. At this point values is a tree of Sum, Product, Negate, and Invert nodes, with other types of values at the leaf nodes. Process the leaf nodes.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    //     For every leaf node leaf in values:
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    bool  parsing_failed_for_child_node  =  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    TRY ( single_value . value ( ) - > for_each_child_node ( [ & ] ( NonnullOwnPtr < CalculationNode > &  node )  - >  ErrorOr < void >  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( node - > type ( )  ! =  CalculationNode : : Type : : Unparsed ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  unparsed_node  =  static_cast < UnparsedCalculationNode & > ( * node ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        auto &  component_value  =  unparsed_node . component_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-03-31 15:10:34 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
										 
							
							
								        // 1. If leaf is a parenthesized simple block, replace leaf with the result of parsing a calculation from leaf’  
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        if  ( component_value . is_block ( )  & &  component_value . block ( ) . is_paren ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto  leaf_calculation  =  TRY ( parse_a_calculation ( component_value . block ( ) . values ( ) ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! leaf_calculation )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                parsing_failed_for_child_node  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            node  =  leaf_calculation . release_nonnull ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-23 13:52:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // 2. If leaf is a math function, replace leaf with the internal representation of that math function.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: All function tokens at this point should be math functions.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        else  if  ( component_value . is_function ( ) )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            auto &  function  =  component_value . function ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 20:56:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								            auto  leaf_calculation  =  TRY ( parse_a_calc_function_node ( function ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            if  ( ! leaf_calculation )  { 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								                parsing_failed_for_child_node  =  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								                return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            } 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-30 20:56:09 +02:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            node  =  leaf_calculation . release_nonnull ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								            return  { } ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        } 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-23 13:52:58 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        // NOTE: If we get here, then we have an UnparsedCalculationNode that didn't get replaced with something else.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        //       So, the calc() is invalid.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        dbgln_if ( CSS_PARSER_DEBUG ,  " Leftover UnparsedCalculationNode in calc tree! That probably means the syntax is invalid, but maybe we just didn't implement `{}` yet. " ,  component_value . to_debug_string ( ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        parsing_failed_for_child_node  =  true ; 
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  { } ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    } ) ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( parsing_failed_for_child_node ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-04-11 15:48:06 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    // FIXME: 6. Return the result of simplifying a calculation tree from values.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  single_value . release_value ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-07-28 16:30:59 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2021-11-11 00:55:02 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : has_ignored_vendor_prefix ( StringView  string )  
						 
					
						
							
								
									
										
										
										
											2021-09-12 16:49:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( ! string . starts_with ( ' - ' ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( string . starts_with ( " -- " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 16:49:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-07-11 17:32:29 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( string . starts_with ( " -libweb- " sv ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2021-09-12 16:49:09 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  false ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  true ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : is_builtin ( StringView  name )  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2023-03-10 08:48:54 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  name . equals_ignoring_ascii_case ( " inherit " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  name . equals_ignoring_ascii_case ( " initial " sv ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        | |  name . equals_ignoring_ascii_case ( " unset " sv ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-03-28 20:32:28 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < CalculatedStyleValue > >  Parser : : parse_calculated_value ( Badge < StyleComputer > ,  ParsingContext  const &  context ,  Vector < ComponentValue >  const &  tokens )  
						 
					
						
							
								
									
										
										
										
											2022-11-02 20:25:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . is_empty ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 20:25:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parser  =  TRY ( Parser : : create ( context ,  " " sv ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-11-02 20:25:50 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  parser . parse_calculated_value ( tokens ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								ErrorOr < RefPtr < StyleValue > >  Parser : : parse_css_value ( Badge < StyleComputer > ,  ParsingContext  const &  context ,  PropertyID  property_id ,  Vector < ComponentValue >  const &  tokens )  
						 
					
						
							
								
									
										
										
										
											2021-12-03 12:32:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( tokens . is_empty ( )  | |  property_id  = =  CSS : : PropertyID : : Invalid  | |  property_id  = =  CSS : : PropertyID : : Custom ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-03 12:32:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  parser  =  TRY ( Parser : : create ( context ,  " " sv ) ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-04-12 12:00:07 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    TokenStream < ComponentValue >  token_stream  {  tokens  } ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-03 12:32:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    auto  result  =  parser . parse_css_value ( property_id ,  token_stream ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( result . is_error ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2023-05-02 13:03:51 +01:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								        return  nullptr ; 
							 
						 
					
						
							
								
									
										
										
										
											2021-12-03 12:32:12 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  result . release_value ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : Dimension : : is_angle ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . has < Angle > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Angle  Parser : : Dimension : : angle ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . get < Angle > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : Dimension : : is_angle_percentage ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  is_angle ( )  | |  is_percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								AnglePercentage  Parser : : Dimension : : angle_percentage ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_angle ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  angle ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : Dimension : : is_frequency ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . has < Frequency > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Frequency  Parser : : Dimension : : frequency ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . get < Frequency > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : Dimension : : is_frequency_percentage ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  is_frequency ( )  | |  is_percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								FrequencyPercentage  Parser : : Dimension : : frequency_percentage ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_frequency ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  frequency ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : Dimension : : is_length ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . has < Length > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Length  Parser : : Dimension : : length ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . get < Length > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : Dimension : : is_length_percentage ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  is_length ( )  | |  is_percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								LengthPercentage  Parser : : Dimension : : length_percentage ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_length ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  length ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : Dimension : : is_percentage ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . has < Percentage > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Percentage  Parser : : Dimension : : percentage ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . get < Percentage > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : Dimension : : is_resolution ( )  const  
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . has < Resolution > ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								Resolution  Parser : : Dimension : : resolution ( )  const  
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
									
										
										
										
											2022-02-22 12:48:59 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . get < Resolution > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : Dimension : : is_time ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . has < Time > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								Time  Parser : : Dimension : : time ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  m_value . get < Time > ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								bool  Parser : : Dimension : : is_time_percentage ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    return  is_time ( )  | |  is_percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								TimePercentage  Parser : : Dimension : : time_percentage ( )  const  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								{  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_time ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  time ( ) ; 
							 
						 
					
						
							
								
									
										
										
										
											2022-01-14 17:09:02 +00:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
								
									
								 
							
							
								    if  ( is_percentage ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								        return  percentage ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								    VERIFY_NOT_REACHED ( ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2021-03-22 17:41:47 +01:00 
										
									 
								 
							 
							
								
							 
							
								 
							
								
									
								 
							
							
								}