mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2024-11-14 11:54:53 +03:00
LibWeb: Parse multiple backgrounds :^)
Like the `background-foo` longhand properties (except `background-color`), `background` allows multiple layers to be defined, separated by commas. A layer does not necessarily contain something to actually draw! This parses as a `BackgroundStyleValue`, holding a `StyleValueList` for each property. This is mostly to make expansion into longhands simpler - if we had a list of `BackgroundStyleValue`s instead, one per layer, then we would have to break it up per-property anyway when computing styles.
This commit is contained in:
parent
8fd4678e79
commit
72d080b4ba
Notes:
sideshowbarker
2024-07-18 01:02:39 +09:00
Author: https://github.com/AtkinsSJ Commit: https://github.com/SerenityOS/serenity/commit/72d080b4bab Pull-request: https://github.com/SerenityOS/serenity/pull/10946
@ -2383,7 +2383,16 @@ RefPtr<StyleValue> Parser::parse_simple_comma_separated_value_list(Vector<StyleC
|
||||
|
||||
RefPtr<StyleValue> Parser::parse_background_value(Vector<StyleComponentValueRule> const& component_values)
|
||||
{
|
||||
NonnullRefPtrVector<StyleValue> background_images;
|
||||
NonnullRefPtrVector<StyleValue> background_positions;
|
||||
NonnullRefPtrVector<StyleValue> background_sizes;
|
||||
NonnullRefPtrVector<StyleValue> background_repeats;
|
||||
NonnullRefPtrVector<StyleValue> background_attachments;
|
||||
NonnullRefPtrVector<StyleValue> background_clips;
|
||||
NonnullRefPtrVector<StyleValue> background_origins;
|
||||
RefPtr<StyleValue> background_color;
|
||||
|
||||
// Per-layer values
|
||||
RefPtr<StyleValue> background_image;
|
||||
RefPtr<StyleValue> background_position;
|
||||
RefPtr<StyleValue> background_size;
|
||||
@ -2392,14 +2401,54 @@ RefPtr<StyleValue> Parser::parse_background_value(Vector<StyleComponentValueRule
|
||||
RefPtr<StyleValue> background_clip;
|
||||
RefPtr<StyleValue> background_origin;
|
||||
|
||||
bool has_multiple_layers = false;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
auto complete_background_layer = [&]() {
|
||||
background_images.append(background_image ? background_image.release_nonnull() : property_initial_value(PropertyID::BackgroundImage));
|
||||
background_positions.append(background_position ? background_position.release_nonnull() : property_initial_value(PropertyID::BackgroundPosition));
|
||||
background_sizes.append(background_size ? background_size.release_nonnull() : property_initial_value(PropertyID::BackgroundSize));
|
||||
background_repeats.append(background_repeat ? background_repeat.release_nonnull() : property_initial_value(PropertyID::BackgroundRepeat));
|
||||
background_attachments.append(background_attachment ? background_attachment.release_nonnull() : property_initial_value(PropertyID::BackgroundAttachment));
|
||||
|
||||
if (!background_origin && !background_clip) {
|
||||
background_origin = property_initial_value(PropertyID::BackgroundOrigin);
|
||||
background_clip = property_initial_value(PropertyID::BackgroundClip);
|
||||
} else if (!background_clip) {
|
||||
background_clip = background_origin;
|
||||
}
|
||||
background_origins.append(background_origin.release_nonnull());
|
||||
background_clips.append(background_clip.release_nonnull());
|
||||
|
||||
background_image = nullptr;
|
||||
background_position = nullptr;
|
||||
background_size = nullptr;
|
||||
background_repeat = nullptr;
|
||||
background_attachment = nullptr;
|
||||
background_clip = nullptr;
|
||||
background_origin = nullptr;
|
||||
};
|
||||
|
||||
auto tokens = TokenStream { component_values };
|
||||
while (tokens.has_next_token()) {
|
||||
auto& part = tokens.next_token();
|
||||
|
||||
// FIXME: Handle multiple backgrounds, by returning a List of BackgroundStyleValues.
|
||||
if (part.is(Token::Type::Comma)) {
|
||||
dbgln("CSS Parser does not yet support multiple comma-separated values for background.");
|
||||
break;
|
||||
has_multiple_layers = true;
|
||||
if (!background_layer_is_valid(false))
|
||||
return nullptr;
|
||||
complete_background_layer();
|
||||
continue;
|
||||
}
|
||||
|
||||
auto value = parse_css_value(part);
|
||||
@ -2478,6 +2527,27 @@ RefPtr<StyleValue> Parser::parse_background_value(Vector<StyleComponentValueRule
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
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) {
|
||||
complete_background_layer();
|
||||
|
||||
if (!background_color)
|
||||
background_color = property_initial_value(PropertyID::BackgroundColor);
|
||||
return BackgroundStyleValue::create(
|
||||
background_color.release_nonnull(),
|
||||
StyleValueList::create(move(background_images)),
|
||||
StyleValueList::create(move(background_positions)),
|
||||
StyleValueList::create(move(background_sizes)),
|
||||
StyleValueList::create(move(background_repeats)),
|
||||
StyleValueList::create(move(background_attachments)),
|
||||
StyleValueList::create(move(background_origins)),
|
||||
StyleValueList::create(move(background_clips)));
|
||||
}
|
||||
|
||||
if (!background_color)
|
||||
background_color = property_initial_value(PropertyID::BackgroundColor);
|
||||
if (!background_image)
|
||||
|
Loading…
Reference in New Issue
Block a user