mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 08:32:43 +00:00 
			
		
		
		
	LibWeb: Parse multiple box-shadows :^)
Again, we don't yet render these (we render nothing) but this gets rid of a decent amount of CSS spam on Discord.
This commit is contained in:
		
							parent
							
								
									e5b0369dfd
								
							
						
					
					
						commit
						b51f428165
					
				
					 3 changed files with 46 additions and 21 deletions
				
			
		|  | @ -37,5 +37,9 @@ | |||
|   <p>box-shadow: 20px 10px 5px magenta</p> | ||||
| </div> | ||||
| 
 | ||||
| <div class="box" style="box-shadow: 20px 10px 5px magenta, cyan -20px -10px 5px, yellow 10px -5px 5px 20px"> | ||||
|   <p>box-shadow: 20px 10px 5px magenta, cyan -20px -10px 5px, yellow 10px -5px 5px 20px</p> | ||||
| </div> | ||||
| 
 | ||||
| </body> | ||||
| </html> | ||||
|  |  | |||
|  | @ -3169,7 +3169,19 @@ RefPtr<StyleValue> Parser::parse_box_shadow_value(Vector<StyleComponentValueRule | |||
|             return ident; | ||||
|     } | ||||
| 
 | ||||
|     // FIXME: Also support multiple comma-separated box-shadows
 | ||||
|     return parse_comma_separated_value_list(component_values, [this](auto& tokens) { | ||||
|         return parse_single_box_shadow_value(tokens); | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| RefPtr<StyleValue> Parser::parse_single_box_shadow_value(TokenStream<StyleComponentValueRule>& tokens) | ||||
| { | ||||
|     auto start_position = tokens.position(); | ||||
|     auto error = [&]() { | ||||
|         tokens.rewind_to_position(start_position); | ||||
|         return nullptr; | ||||
|     }; | ||||
| 
 | ||||
|     Optional<Color> color; | ||||
|     Optional<Length> offset_x; | ||||
|     Optional<Length> offset_y; | ||||
|  | @ -3177,58 +3189,66 @@ RefPtr<StyleValue> Parser::parse_box_shadow_value(Vector<StyleComponentValueRule | |||
|     Optional<Length> spread_distance; | ||||
|     Optional<BoxShadowPlacement> placement; | ||||
| 
 | ||||
|     for (size_t i = 0; i < component_values.size(); ++i) { | ||||
|         if (auto maybe_color = parse_color(component_values[i]); maybe_color.has_value()) { | ||||
|     while (tokens.has_next_token()) { | ||||
|         auto& token = tokens.peek_token(); | ||||
| 
 | ||||
|         if (auto maybe_color = parse_color(token); maybe_color.has_value()) { | ||||
|             if (color.has_value()) | ||||
|                 return nullptr; | ||||
|                 return error(); | ||||
|             color = maybe_color.release_value(); | ||||
|             tokens.next_token(); | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if (auto maybe_offset_x = parse_length(component_values[i]); maybe_offset_x.has_value()) { | ||||
|         if (auto maybe_offset_x = parse_length(token); maybe_offset_x.has_value()) { | ||||
|             // horizontal offset
 | ||||
|             if (offset_x.has_value()) | ||||
|                 return nullptr; | ||||
|                 return error(); | ||||
|             offset_x = maybe_offset_x.release_value(); | ||||
|             tokens.next_token(); | ||||
| 
 | ||||
|             // vertical offset
 | ||||
|             if (++i >= component_values.size()) | ||||
|                 return nullptr; | ||||
|             auto maybe_offset_y = parse_length(component_values[i]); | ||||
|             if (!tokens.has_next_token()) | ||||
|                 return error(); | ||||
|             auto maybe_offset_y = parse_length(tokens.peek_token()); | ||||
|             if (!maybe_offset_y.has_value()) | ||||
|                 return nullptr; | ||||
|                 return error(); | ||||
|             offset_y = maybe_offset_y.release_value(); | ||||
|             tokens.next_token(); | ||||
| 
 | ||||
|             // blur radius (optional)
 | ||||
|             if (i + 1 >= component_values.size()) | ||||
|             if (!tokens.has_next_token()) | ||||
|                 break; | ||||
|             auto maybe_blur_radius = parse_length(component_values[i + 1]); | ||||
|             auto maybe_blur_radius = parse_length(tokens.peek_token()); | ||||
|             if (!maybe_blur_radius.has_value()) | ||||
|                 continue; | ||||
|             ++i; | ||||
|             blur_radius = maybe_blur_radius.release_value(); | ||||
|             tokens.next_token(); | ||||
| 
 | ||||
|             // spread distance (optional)
 | ||||
|             if (i + 1 >= component_values.size()) | ||||
|             if (!tokens.has_next_token()) | ||||
|                 break; | ||||
|             auto maybe_spread_distance = parse_length(component_values[i + 1]); | ||||
|             auto maybe_spread_distance = parse_length(tokens.peek_token()); | ||||
|             if (!maybe_spread_distance.has_value()) | ||||
|                 continue; | ||||
|             ++i; | ||||
|             spread_distance = maybe_spread_distance.release_value(); | ||||
|             tokens.next_token(); | ||||
| 
 | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         if (component_values[i].is(Token::Type::Ident) && component_values[i].token().ident().equals_ignoring_case("inset"sv)) { | ||||
|         if (token.is(Token::Type::Ident) && token.token().ident().equals_ignoring_case("inset"sv)) { | ||||
|             if (placement.has_value()) | ||||
|                 return nullptr; | ||||
|                 return error(); | ||||
|             placement = BoxShadowPlacement::Inner; | ||||
|             tokens.next_token(); | ||||
|             continue; | ||||
|         } | ||||
| 
 | ||||
|         // Unrecognized value
 | ||||
|         return nullptr; | ||||
|         if (token.is(Token::Type::Comma)) | ||||
|             break; | ||||
| 
 | ||||
|         return error(); | ||||
|     } | ||||
| 
 | ||||
|     // FIXME: If color is absent, default to `currentColor`
 | ||||
|  | @ -3237,7 +3257,7 @@ RefPtr<StyleValue> Parser::parse_box_shadow_value(Vector<StyleComponentValueRule | |||
| 
 | ||||
|     // x/y offsets are required
 | ||||
|     if (!offset_x.has_value() || !offset_y.has_value()) | ||||
|         return nullptr; | ||||
|         return error(); | ||||
| 
 | ||||
|     // Other lengths default to 0
 | ||||
|     if (!blur_radius.has_value()) | ||||
|  |  | |||
|  | @ -232,6 +232,7 @@ private: | |||
|     RefPtr<StyleValue> parse_border_radius_value(Vector<StyleComponentValueRule> const&); | ||||
|     RefPtr<StyleValue> parse_border_radius_shorthand_value(Vector<StyleComponentValueRule> const&); | ||||
|     RefPtr<StyleValue> parse_box_shadow_value(Vector<StyleComponentValueRule> const&); | ||||
|     RefPtr<StyleValue> parse_single_box_shadow_value(TokenStream<StyleComponentValueRule>&); | ||||
|     RefPtr<StyleValue> parse_flex_value(Vector<StyleComponentValueRule> const&); | ||||
|     RefPtr<StyleValue> parse_flex_flow_value(Vector<StyleComponentValueRule> const&); | ||||
|     RefPtr<StyleValue> parse_font_value(Vector<StyleComponentValueRule> const&); | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Sam Atkins
						Sam Atkins