mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-28 13:18:19 +00:00
LibWeb/CSS: Serialize mask shorthand-property properly
This commit is contained in:
parent
39b64c9b5c
commit
6c4483fe0e
Notes:
github-actions[bot]
2025-08-06 22:10:14 +00:00
Author: https://github.com/InvalidUsernameException
Commit: 6c4483fe0e
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/5511
Reviewed-by: https://github.com/AtkinsSJ ✅
Reviewed-by: https://github.com/Calme1709
4 changed files with 147 additions and 38 deletions
|
@ -489,6 +489,116 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
|
|||
return start->to_string(mode);
|
||||
return MUST(String::formatted("{} / {}", start->to_string(mode), end->to_string(mode)));
|
||||
}
|
||||
case PropertyID::Mask: {
|
||||
StringBuilder builder;
|
||||
|
||||
auto serialize_layer = [mode, &builder](String image_value_string, String position_value_string, String size_value_string, String repeat_value_string, String origin_value_string, String clip_value_string, String composite_value_string, String mode_value_string) {
|
||||
PropertyID canonical_property_order[] = {
|
||||
PropertyID::MaskImage,
|
||||
PropertyID::MaskPosition,
|
||||
// Intentionally skipping MaskSize here, it is handled together with MaskPosition.
|
||||
PropertyID::MaskRepeat,
|
||||
PropertyID::MaskOrigin,
|
||||
PropertyID::MaskClip,
|
||||
PropertyID::MaskComposite,
|
||||
PropertyID::MaskMode,
|
||||
};
|
||||
|
||||
auto property_value = [&](PropertyID property) -> String const& {
|
||||
switch (property) {
|
||||
case PropertyID::MaskImage:
|
||||
return image_value_string;
|
||||
case PropertyID::MaskPosition:
|
||||
return position_value_string;
|
||||
case PropertyID::MaskSize:
|
||||
return size_value_string;
|
||||
case PropertyID::MaskRepeat:
|
||||
return repeat_value_string;
|
||||
case PropertyID::MaskOrigin:
|
||||
return origin_value_string;
|
||||
case PropertyID::MaskClip:
|
||||
return clip_value_string;
|
||||
case PropertyID::MaskComposite:
|
||||
return composite_value_string;
|
||||
case PropertyID::MaskMode:
|
||||
return mode_value_string;
|
||||
default:
|
||||
VERIFY_NOT_REACHED();
|
||||
}
|
||||
};
|
||||
|
||||
auto is_initial_value = [mode, property_value](PropertyID property) -> bool {
|
||||
return property_value(property) == property_initial_value(property)->to_string(mode);
|
||||
};
|
||||
|
||||
auto can_skip_serializing_initial_value = [is_initial_value, property_value](PropertyID property) -> bool {
|
||||
switch (property) {
|
||||
case PropertyID::MaskPosition:
|
||||
return is_initial_value(PropertyID::MaskSize);
|
||||
case PropertyID::MaskOrigin:
|
||||
return is_initial_value(PropertyID::MaskClip) || property_value(PropertyID::MaskClip) == string_from_keyword(Keyword::NoClip);
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
bool layer_is_empty = true;
|
||||
for (size_t i = 0; i < array_size(canonical_property_order); i++) {
|
||||
auto property = canonical_property_order[i];
|
||||
auto const& value = property_value(property);
|
||||
|
||||
if (is_initial_value(property) && can_skip_serializing_initial_value(property))
|
||||
continue;
|
||||
if (property == PropertyID::MaskClip && value == property_value(PropertyID::MaskOrigin))
|
||||
continue;
|
||||
|
||||
if (!layer_is_empty)
|
||||
builder.append(" "sv);
|
||||
builder.append(value);
|
||||
if (property == PropertyID::MaskPosition && !is_initial_value(PropertyID::MaskSize)) {
|
||||
builder.append(" / "sv);
|
||||
builder.append(property_value(PropertyID::MaskSize));
|
||||
}
|
||||
layer_is_empty = false;
|
||||
}
|
||||
|
||||
if (layer_is_empty)
|
||||
builder.append("none"sv);
|
||||
};
|
||||
|
||||
auto get_layer_count = [](auto const& style_value) -> size_t {
|
||||
return style_value->is_value_list() ? style_value->as_value_list().size() : 1;
|
||||
};
|
||||
|
||||
auto mask_image = longhand(PropertyID::MaskImage);
|
||||
auto mask_position = longhand(PropertyID::MaskPosition);
|
||||
auto mask_size = longhand(PropertyID::MaskSize);
|
||||
auto mask_repeat = longhand(PropertyID::MaskRepeat);
|
||||
auto mask_origin = longhand(PropertyID::MaskOrigin);
|
||||
auto mask_clip = longhand(PropertyID::MaskClip);
|
||||
auto mask_composite = longhand(PropertyID::MaskComposite);
|
||||
auto mask_mode = longhand(PropertyID::MaskMode);
|
||||
|
||||
auto layer_count = max(get_layer_count(mask_image), max(get_layer_count(mask_position), max(get_layer_count(mask_size), max(get_layer_count(mask_repeat), max(get_layer_count(mask_origin), max(get_layer_count(mask_clip), max(get_layer_count(mask_composite), get_layer_count(mask_mode))))))));
|
||||
|
||||
if (layer_count == 1) {
|
||||
serialize_layer(mask_image->to_string(mode), mask_position->to_string(mode), mask_size->to_string(mode), mask_repeat->to_string(mode), mask_origin->to_string(mode), mask_clip->to_string(mode), mask_composite->to_string(mode), mask_mode->to_string(mode));
|
||||
} else {
|
||||
auto get_layer_value_string = [mode](ValueComparingRefPtr<CSSStyleValue const> const& style_value, size_t index) {
|
||||
if (style_value->is_value_list())
|
||||
return style_value->as_value_list().value_at(index, true)->to_string(mode);
|
||||
return style_value->to_string(mode);
|
||||
};
|
||||
|
||||
for (size_t i = 0; i < layer_count; i++) {
|
||||
if (i)
|
||||
builder.append(", "sv);
|
||||
|
||||
serialize_layer(get_layer_value_string(mask_image, i), get_layer_value_string(mask_position, i), get_layer_value_string(mask_size, i), get_layer_value_string(mask_repeat, i), get_layer_value_string(mask_origin, i), get_layer_value_string(mask_clip, i), get_layer_value_string(mask_composite, i), get_layer_value_string(mask_mode, i));
|
||||
}
|
||||
}
|
||||
return builder.to_string_without_validation();
|
||||
}
|
||||
case PropertyID::PlaceContent:
|
||||
case PropertyID::PlaceItems:
|
||||
case PropertyID::PlaceSelf:
|
||||
|
|
|
@ -111,9 +111,9 @@ All supported properties and their default values exposed from CSSStylePropertie
|
|||
'WebkitJustifyContent': 'normal'
|
||||
'webkitJustifyContent': 'normal'
|
||||
'-webkit-justify-content': 'normal'
|
||||
'WebkitMask': 'border-box'
|
||||
'webkitMask': 'border-box'
|
||||
'-webkit-mask': 'border-box'
|
||||
'WebkitMask': 'none'
|
||||
'webkitMask': 'none'
|
||||
'-webkit-mask': 'none'
|
||||
'WebkitMaskImage': 'none'
|
||||
'webkitMaskImage': 'none'
|
||||
'-webkit-mask-image': 'none'
|
||||
|
@ -524,7 +524,7 @@ All supported properties and their default values exposed from CSSStylePropertie
|
|||
'margin-right': '8px'
|
||||
'marginTop': '8px'
|
||||
'margin-top': '8px'
|
||||
'mask': 'border-box'
|
||||
'mask': 'none'
|
||||
'maskClip': 'border-box'
|
||||
'mask-clip': 'border-box'
|
||||
'maskComposite': 'add'
|
||||
|
|
|
@ -2,32 +2,31 @@ Harness status: OK
|
|||
|
||||
Found 27 tests
|
||||
|
||||
12 Pass
|
||||
15 Fail
|
||||
Fail Property mask value 'none'
|
||||
27 Pass
|
||||
Pass Property mask value 'none'
|
||||
Pass Property mask value 'linear-gradient(to left bottom, red, blue)'
|
||||
Pass Property mask value 'linear-gradient(to left bottom, red, blue) luminance'
|
||||
Pass Property mask value 'url("https://example.com/")'
|
||||
Pass Property mask value 'linear-gradient(to left bottom, red, blue) 1px 2px'
|
||||
Fail Property mask value 'url("https://example.com/") 1px 2px / contain'
|
||||
Pass Property mask value 'url("https://example.com/") 1px 2px / contain'
|
||||
Pass Property mask value 'repeat-y'
|
||||
Fail Property mask value 'border-box'
|
||||
Fail Property mask value 'linear-gradient(to left bottom, red, blue) padding-box'
|
||||
Fail Property mask value 'content-box'
|
||||
Fail Property mask value 'url("https://example.com/") fill-box'
|
||||
Fail Property mask value 'linear-gradient(to left bottom, red, blue) stroke-box'
|
||||
Fail Property mask value 'view-box'
|
||||
Pass Property mask value 'border-box'
|
||||
Pass Property mask value 'linear-gradient(to left bottom, red, blue) padding-box'
|
||||
Pass Property mask value 'content-box'
|
||||
Pass Property mask value 'url("https://example.com/") fill-box'
|
||||
Pass Property mask value 'linear-gradient(to left bottom, red, blue) stroke-box'
|
||||
Pass Property mask value 'view-box'
|
||||
Pass Property mask value 'no-clip'
|
||||
Pass Property mask value 'url("https://example.com/") add'
|
||||
Pass Property mask value 'subtract'
|
||||
Fail Property mask value 'url("https://example.com/") intersect'
|
||||
Fail Property mask value 'linear-gradient(to left bottom, red, blue) exclude'
|
||||
Pass Property mask value 'url("https://example.com/") intersect'
|
||||
Pass Property mask value 'linear-gradient(to left bottom, red, blue) exclude'
|
||||
Pass Property mask value 'alpha'
|
||||
Pass Property mask value 'url("https://example.com/") alpha'
|
||||
Fail Property mask value 'border-box border-box'
|
||||
Fail Property mask value 'content-box content-box'
|
||||
Fail Property mask value 'border-box content-box'
|
||||
Pass Property mask value 'border-box border-box'
|
||||
Pass Property mask value 'content-box content-box'
|
||||
Pass Property mask value 'border-box content-box'
|
||||
Pass Property mask value 'border-box no-clip'
|
||||
Fail Property mask value 'intersect no-clip space round 1px 2px / contain stroke-box linear-gradient(to left bottom, red, blue) luminance'
|
||||
Fail Property mask value 'intersect no-clip space round 1px 2px / contain view-box, stroke-box linear-gradient(to left bottom, red, blue) luminance'
|
||||
Pass Property mask value 'intersect no-clip space round 1px 2px / contain stroke-box linear-gradient(to left bottom, red, blue) luminance'
|
||||
Pass Property mask value 'intersect no-clip space round 1px 2px / contain view-box, stroke-box linear-gradient(to left bottom, red, blue) luminance'
|
||||
Pass Property mask value 'none alpha'
|
|
@ -2,34 +2,34 @@ Harness status: OK
|
|||
|
||||
Found 55 tests
|
||||
|
||||
25 Pass
|
||||
30 Fail
|
||||
Fail e.style['mask'] = "none" should set the property value
|
||||
40 Pass
|
||||
15 Fail
|
||||
Pass e.style['mask'] = "none" should set the property value
|
||||
Pass e.style['mask'] = "linear-gradient(to left bottom, red, blue)" should set the property value
|
||||
Pass e.style['mask'] = "linear-gradient(to left bottom, red, blue) luminance" should set the property value
|
||||
Pass e.style['mask'] = "url(\"https://wpt.live/\")" should set the property value
|
||||
Pass e.style['mask'] = "linear-gradient(to left bottom, red, blue) 1px 2px" should set the property value
|
||||
Fail e.style['mask'] = "url(\"https://wpt.live/\") 1px 2px / contain" should set the property value
|
||||
Pass e.style['mask'] = "url(\"https://wpt.live/\") 1px 2px / contain" should set the property value
|
||||
Pass e.style['mask'] = "repeat-y" should set the property value
|
||||
Fail e.style['mask'] = "border-box" should set the property value
|
||||
Fail e.style['mask'] = "linear-gradient(to left bottom, red, blue) padding-box" should set the property value
|
||||
Fail e.style['mask'] = "content-box" should set the property value
|
||||
Fail e.style['mask'] = "url(\"https://wpt.live/\") fill-box" should set the property value
|
||||
Fail e.style['mask'] = "linear-gradient(to left bottom, red, blue) stroke-box" should set the property value
|
||||
Fail e.style['mask'] = "view-box" should set the property value
|
||||
Pass e.style['mask'] = "border-box" should set the property value
|
||||
Pass e.style['mask'] = "linear-gradient(to left bottom, red, blue) padding-box" should set the property value
|
||||
Pass e.style['mask'] = "content-box" should set the property value
|
||||
Pass e.style['mask'] = "url(\"https://wpt.live/\") fill-box" should set the property value
|
||||
Pass e.style['mask'] = "linear-gradient(to left bottom, red, blue) stroke-box" should set the property value
|
||||
Pass e.style['mask'] = "view-box" should set the property value
|
||||
Pass e.style['mask'] = "no-clip" should set the property value
|
||||
Pass e.style['mask'] = "url(\"https://wpt.live/\") add" should set the property value
|
||||
Pass e.style['mask'] = "subtract" should set the property value
|
||||
Fail e.style['mask'] = "url(\"https://wpt.live/\") intersect" should set the property value
|
||||
Fail e.style['mask'] = "linear-gradient(to left bottom, red, blue) exclude" should set the property value
|
||||
Pass e.style['mask'] = "url(\"https://wpt.live/\") intersect" should set the property value
|
||||
Pass e.style['mask'] = "linear-gradient(to left bottom, red, blue) exclude" should set the property value
|
||||
Pass e.style['mask'] = "alpha" should set the property value
|
||||
Pass e.style['mask'] = "url(\"https://wpt.live/\") alpha" should set the property value
|
||||
Fail e.style['mask'] = "border-box border-box" should set the property value
|
||||
Fail e.style['mask'] = "content-box content-box" should set the property value
|
||||
Fail e.style['mask'] = "border-box content-box" should set the property value
|
||||
Pass e.style['mask'] = "border-box border-box" should set the property value
|
||||
Pass e.style['mask'] = "content-box content-box" should set the property value
|
||||
Pass e.style['mask'] = "border-box content-box" should set the property value
|
||||
Pass e.style['mask'] = "border-box no-clip" should set the property value
|
||||
Fail e.style['mask'] = "intersect no-clip space round 1px 2px / contain stroke-box linear-gradient(to left bottom, red, blue) luminance" should set the property value
|
||||
Fail e.style['mask'] = "intersect no-clip space round 1px 2px / contain view-box, stroke-box linear-gradient(to left bottom, red, blue) luminance" should set the property value
|
||||
Pass e.style['mask'] = "intersect no-clip space round 1px 2px / contain stroke-box linear-gradient(to left bottom, red, blue) luminance" should set the property value
|
||||
Pass e.style['mask'] = "intersect no-clip space round 1px 2px / contain view-box, stroke-box linear-gradient(to left bottom, red, blue) luminance" should set the property value
|
||||
Pass e.style['mask'] = "none alpha" should set the property value
|
||||
Fail e.style['mask'] = "none" should set mask-border-outset
|
||||
Fail e.style['mask'] = "none" should set mask-border-repeat
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue