mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-08-02 14:19:48 +00:00
LibWeb/CSS: Don't serialize longhands which match their initial values
Shorthand subproperties that match their initial values are now excluded from serialization, by default. Properties where this behavior is not desired, like `gap`, are special-cased.
This commit is contained in:
parent
b4b8d85251
commit
3186adeaa1
Notes:
github-actions[bot]
2025-04-07 10:40:16 +00:00
Author: https://github.com/tcl3
Commit: 3186adeaa1
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4259
Reviewed-by: https://github.com/AtkinsSJ ✅
6 changed files with 144 additions and 27 deletions
|
@ -279,6 +279,13 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
|
||||||
return "normal"_string;
|
return "normal"_string;
|
||||||
return MUST(String::join(' ', values));
|
return MUST(String::join(' ', values));
|
||||||
}
|
}
|
||||||
|
case PropertyID::Gap: {
|
||||||
|
auto row_gap = longhand(PropertyID::RowGap);
|
||||||
|
auto column_gap = longhand(PropertyID::ColumnGap);
|
||||||
|
if (row_gap == column_gap)
|
||||||
|
return row_gap->to_string(mode);
|
||||||
|
return MUST(String::formatted("{} {}", row_gap->to_string(mode), column_gap->to_string(mode)));
|
||||||
|
}
|
||||||
case PropertyID::GridArea: {
|
case PropertyID::GridArea: {
|
||||||
auto& row_start = longhand(PropertyID::GridRowStart)->as_grid_track_placement();
|
auto& row_start = longhand(PropertyID::GridRowStart)->as_grid_track_placement();
|
||||||
auto& column_start = longhand(PropertyID::GridColumnStart)->as_grid_track_placement();
|
auto& column_start = longhand(PropertyID::GridColumnStart)->as_grid_track_placement();
|
||||||
|
@ -411,13 +418,21 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
|
||||||
|
|
||||||
StringBuilder builder;
|
StringBuilder builder;
|
||||||
auto first = true;
|
auto first = true;
|
||||||
for (auto& value : m_properties.values) {
|
for (size_t i = 0; i < m_properties.values.size(); ++i) {
|
||||||
|
auto value = m_properties.values[i];
|
||||||
|
auto value_string = value->to_string(mode);
|
||||||
|
auto initial_value_string = property_initial_value(m_properties.sub_properties[i])->to_string(mode);
|
||||||
|
if (value_string == initial_value_string)
|
||||||
|
continue;
|
||||||
if (first)
|
if (first)
|
||||||
first = false;
|
first = false;
|
||||||
else
|
else
|
||||||
builder.append(' ');
|
builder.append(' ');
|
||||||
builder.append(value->to_string(mode));
|
builder.append(value->to_string(mode));
|
||||||
}
|
}
|
||||||
|
if (builder.is_empty())
|
||||||
|
return m_properties.values.first()->to_string(mode);
|
||||||
|
|
||||||
return MUST(builder.to_string());
|
return MUST(builder.to_string());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,9 +9,9 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'WebkitAlignSelf': 'auto'
|
'WebkitAlignSelf': 'auto'
|
||||||
'webkitAlignSelf': 'auto'
|
'webkitAlignSelf': 'auto'
|
||||||
'-webkit-align-self': 'auto'
|
'-webkit-align-self': 'auto'
|
||||||
'WebkitAnimation': 'none 0s ease 1 normal running 0s none'
|
'WebkitAnimation': 'none'
|
||||||
'webkitAnimation': 'none 0s ease 1 normal running 0s none'
|
'webkitAnimation': 'none'
|
||||||
'-webkit-animation': 'none 0s ease 1 normal running 0s none'
|
'-webkit-animation': 'none'
|
||||||
'WebkitAnimationDelay': '0s'
|
'WebkitAnimationDelay': '0s'
|
||||||
'webkitAnimationDelay': '0s'
|
'webkitAnimationDelay': '0s'
|
||||||
'-webkit-animation-delay': '0s'
|
'-webkit-animation-delay': '0s'
|
||||||
|
@ -111,9 +111,9 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'WebkitTransformOrigin': '50% 50%'
|
'WebkitTransformOrigin': '50% 50%'
|
||||||
'webkitTransformOrigin': '50% 50%'
|
'webkitTransformOrigin': '50% 50%'
|
||||||
'-webkit-transform-origin': '50% 50%'
|
'-webkit-transform-origin': '50% 50%'
|
||||||
'WebkitTransition': 'all 0s ease 0s'
|
'WebkitTransition': 'all'
|
||||||
'webkitTransition': 'all 0s ease 0s'
|
'webkitTransition': 'all'
|
||||||
'-webkit-transition': 'all 0s ease 0s'
|
'-webkit-transition': 'all'
|
||||||
'WebkitTransitionDelay': '0s'
|
'WebkitTransitionDelay': '0s'
|
||||||
'webkitTransitionDelay': '0s'
|
'webkitTransitionDelay': '0s'
|
||||||
'-webkit-transition-delay': '0s'
|
'-webkit-transition-delay': '0s'
|
||||||
|
@ -137,7 +137,7 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'align-items': 'normal'
|
'align-items': 'normal'
|
||||||
'alignSelf': 'auto'
|
'alignSelf': 'auto'
|
||||||
'align-self': 'auto'
|
'align-self': 'auto'
|
||||||
'animation': 'none 0s ease 1 normal running 0s none'
|
'animation': 'none'
|
||||||
'animationDelay': '0s'
|
'animationDelay': '0s'
|
||||||
'animation-delay': '0s'
|
'animation-delay': '0s'
|
||||||
'animationDirection': 'normal'
|
'animationDirection': 'normal'
|
||||||
|
@ -184,25 +184,25 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'background-size': 'auto auto'
|
'background-size': 'auto auto'
|
||||||
'blockSize': '0px'
|
'blockSize': '0px'
|
||||||
'block-size': '0px'
|
'block-size': '0px'
|
||||||
'border': '0px none rgb(0, 0, 0)'
|
'border': '0px rgb(0, 0, 0)'
|
||||||
'borderBlockEnd': 'medium none rgb(0, 0, 0)'
|
'borderBlockEnd': 'rgb(0, 0, 0)'
|
||||||
'border-block-end': 'medium none rgb(0, 0, 0)'
|
'border-block-end': 'rgb(0, 0, 0)'
|
||||||
'borderBlockEndColor': 'rgb(0, 0, 0)'
|
'borderBlockEndColor': 'rgb(0, 0, 0)'
|
||||||
'border-block-end-color': 'rgb(0, 0, 0)'
|
'border-block-end-color': 'rgb(0, 0, 0)'
|
||||||
'borderBlockEndStyle': 'none'
|
'borderBlockEndStyle': 'none'
|
||||||
'border-block-end-style': 'none'
|
'border-block-end-style': 'none'
|
||||||
'borderBlockEndWidth': 'medium'
|
'borderBlockEndWidth': 'medium'
|
||||||
'border-block-end-width': 'medium'
|
'border-block-end-width': 'medium'
|
||||||
'borderBlockStart': 'medium none rgb(0, 0, 0)'
|
'borderBlockStart': 'rgb(0, 0, 0)'
|
||||||
'border-block-start': 'medium none rgb(0, 0, 0)'
|
'border-block-start': 'rgb(0, 0, 0)'
|
||||||
'borderBlockStartColor': 'rgb(0, 0, 0)'
|
'borderBlockStartColor': 'rgb(0, 0, 0)'
|
||||||
'border-block-start-color': 'rgb(0, 0, 0)'
|
'border-block-start-color': 'rgb(0, 0, 0)'
|
||||||
'borderBlockStartStyle': 'none'
|
'borderBlockStartStyle': 'none'
|
||||||
'border-block-start-style': 'none'
|
'border-block-start-style': 'none'
|
||||||
'borderBlockStartWidth': 'medium'
|
'borderBlockStartWidth': 'medium'
|
||||||
'border-block-start-width': 'medium'
|
'border-block-start-width': 'medium'
|
||||||
'borderBottom': '0px none rgb(0, 0, 0)'
|
'borderBottom': '0px rgb(0, 0, 0)'
|
||||||
'border-bottom': '0px none rgb(0, 0, 0)'
|
'border-bottom': '0px rgb(0, 0, 0)'
|
||||||
'borderBottomColor': 'rgb(0, 0, 0)'
|
'borderBottomColor': 'rgb(0, 0, 0)'
|
||||||
'border-bottom-color': 'rgb(0, 0, 0)'
|
'border-bottom-color': 'rgb(0, 0, 0)'
|
||||||
'borderBottomLeftRadius': '0px'
|
'borderBottomLeftRadius': '0px'
|
||||||
|
@ -217,24 +217,24 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'border-collapse': 'separate'
|
'border-collapse': 'separate'
|
||||||
'borderColor': 'rgb(0, 0, 0)'
|
'borderColor': 'rgb(0, 0, 0)'
|
||||||
'border-color': 'rgb(0, 0, 0)'
|
'border-color': 'rgb(0, 0, 0)'
|
||||||
'borderInlineEnd': 'medium none rgb(0, 0, 0)'
|
'borderInlineEnd': 'rgb(0, 0, 0)'
|
||||||
'border-inline-end': 'medium none rgb(0, 0, 0)'
|
'border-inline-end': 'rgb(0, 0, 0)'
|
||||||
'borderInlineEndColor': 'rgb(0, 0, 0)'
|
'borderInlineEndColor': 'rgb(0, 0, 0)'
|
||||||
'border-inline-end-color': 'rgb(0, 0, 0)'
|
'border-inline-end-color': 'rgb(0, 0, 0)'
|
||||||
'borderInlineEndStyle': 'none'
|
'borderInlineEndStyle': 'none'
|
||||||
'border-inline-end-style': 'none'
|
'border-inline-end-style': 'none'
|
||||||
'borderInlineEndWidth': 'medium'
|
'borderInlineEndWidth': 'medium'
|
||||||
'border-inline-end-width': 'medium'
|
'border-inline-end-width': 'medium'
|
||||||
'borderInlineStart': 'medium none rgb(0, 0, 0)'
|
'borderInlineStart': 'rgb(0, 0, 0)'
|
||||||
'border-inline-start': 'medium none rgb(0, 0, 0)'
|
'border-inline-start': 'rgb(0, 0, 0)'
|
||||||
'borderInlineStartColor': 'rgb(0, 0, 0)'
|
'borderInlineStartColor': 'rgb(0, 0, 0)'
|
||||||
'border-inline-start-color': 'rgb(0, 0, 0)'
|
'border-inline-start-color': 'rgb(0, 0, 0)'
|
||||||
'borderInlineStartStyle': 'none'
|
'borderInlineStartStyle': 'none'
|
||||||
'border-inline-start-style': 'none'
|
'border-inline-start-style': 'none'
|
||||||
'borderInlineStartWidth': 'medium'
|
'borderInlineStartWidth': 'medium'
|
||||||
'border-inline-start-width': 'medium'
|
'border-inline-start-width': 'medium'
|
||||||
'borderLeft': '0px none rgb(0, 0, 0)'
|
'borderLeft': '0px rgb(0, 0, 0)'
|
||||||
'border-left': '0px none rgb(0, 0, 0)'
|
'border-left': '0px rgb(0, 0, 0)'
|
||||||
'borderLeftColor': 'rgb(0, 0, 0)'
|
'borderLeftColor': 'rgb(0, 0, 0)'
|
||||||
'border-left-color': 'rgb(0, 0, 0)'
|
'border-left-color': 'rgb(0, 0, 0)'
|
||||||
'borderLeftStyle': 'none'
|
'borderLeftStyle': 'none'
|
||||||
|
@ -243,8 +243,8 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'border-left-width': '0px'
|
'border-left-width': '0px'
|
||||||
'borderRadius': '0px'
|
'borderRadius': '0px'
|
||||||
'border-radius': '0px'
|
'border-radius': '0px'
|
||||||
'borderRight': '0px none rgb(0, 0, 0)'
|
'borderRight': '0px rgb(0, 0, 0)'
|
||||||
'border-right': '0px none rgb(0, 0, 0)'
|
'border-right': '0px rgb(0, 0, 0)'
|
||||||
'borderRightColor': 'rgb(0, 0, 0)'
|
'borderRightColor': 'rgb(0, 0, 0)'
|
||||||
'border-right-color': 'rgb(0, 0, 0)'
|
'border-right-color': 'rgb(0, 0, 0)'
|
||||||
'borderRightStyle': 'none'
|
'borderRightStyle': 'none'
|
||||||
|
@ -255,8 +255,8 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'border-spacing': '0px'
|
'border-spacing': '0px'
|
||||||
'borderStyle': 'none'
|
'borderStyle': 'none'
|
||||||
'border-style': 'none'
|
'border-style': 'none'
|
||||||
'borderTop': '0px none rgb(0, 0, 0)'
|
'borderTop': '0px rgb(0, 0, 0)'
|
||||||
'border-top': '0px none rgb(0, 0, 0)'
|
'border-top': '0px rgb(0, 0, 0)'
|
||||||
'borderTopColor': 'rgb(0, 0, 0)'
|
'borderTopColor': 'rgb(0, 0, 0)'
|
||||||
'border-top-color': 'rgb(0, 0, 0)'
|
'border-top-color': 'rgb(0, 0, 0)'
|
||||||
'borderTopLeftRadius': '0px'
|
'borderTopLeftRadius': '0px'
|
||||||
|
@ -496,7 +496,7 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'object-position': '50% 50%'
|
'object-position': '50% 50%'
|
||||||
'opacity': '1'
|
'opacity': '1'
|
||||||
'order': '0'
|
'order': '0'
|
||||||
'outline': 'rgb(0, 0, 0) none 0px'
|
'outline': 'rgb(0, 0, 0) 0px'
|
||||||
'outlineColor': 'rgb(0, 0, 0)'
|
'outlineColor': 'rgb(0, 0, 0)'
|
||||||
'outline-color': 'rgb(0, 0, 0)'
|
'outline-color': 'rgb(0, 0, 0)'
|
||||||
'outlineOffset': '0px'
|
'outlineOffset': '0px'
|
||||||
|
@ -606,7 +606,7 @@ All supported properties and their default values exposed from CSSStylePropertie
|
||||||
'transform-box': 'view-box'
|
'transform-box': 'view-box'
|
||||||
'transformOrigin': '50% 50%'
|
'transformOrigin': '50% 50%'
|
||||||
'transform-origin': '50% 50%'
|
'transform-origin': '50% 50%'
|
||||||
'transition': 'all 0s ease 0s'
|
'transition': 'all'
|
||||||
'transitionDelay': '0s'
|
'transitionDelay': '0s'
|
||||||
'transition-delay': '0s'
|
'transition-delay': '0s'
|
||||||
'transitionDuration': '0s'
|
'transitionDuration': '0s'
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 6 tests
|
||||||
|
|
||||||
|
6 Pass
|
||||||
|
Pass e.style['border'] = "1px dotted red" should set the property value
|
||||||
|
Pass e.style['border'] = "green double thin" should set the property value
|
||||||
|
Pass e.style['border-top'] = "thin" should set the property value
|
||||||
|
Pass e.style['border-right'] = "double" should set the property value
|
||||||
|
Pass e.style['border-bottom'] = "green" should set the property value
|
||||||
|
Pass e.style['border-left'] = "1px dotted red" should set the property value
|
|
@ -0,0 +1,25 @@
|
||||||
|
Harness status: OK
|
||||||
|
|
||||||
|
Found 20 tests
|
||||||
|
|
||||||
|
20 Pass
|
||||||
|
Pass e.style['outline'] = "rgba(10, 20, 30, 0.4)" should set the property value
|
||||||
|
Pass e.style['outline'] = "auto" should set the property value
|
||||||
|
Pass e.style['outline'] = "none" should set the property value
|
||||||
|
Pass e.style['outline'] = "dotted" should set the property value
|
||||||
|
Pass e.style['outline'] = "dashed" should set the property value
|
||||||
|
Pass e.style['outline'] = "solid" should set the property value
|
||||||
|
Pass e.style['outline'] = "double" should set the property value
|
||||||
|
Pass e.style['outline'] = "groove" should set the property value
|
||||||
|
Pass e.style['outline'] = "ridge" should set the property value
|
||||||
|
Pass e.style['outline'] = "inset" should set the property value
|
||||||
|
Pass e.style['outline'] = "outset" should set the property value
|
||||||
|
Pass e.style['outline'] = "0" should set the property value
|
||||||
|
Pass e.style['outline'] = "1px" should set the property value
|
||||||
|
Pass e.style['outline'] = "calc(2em + 3ex)" should set the property value
|
||||||
|
Pass e.style['outline'] = "thin" should set the property value
|
||||||
|
Pass e.style['outline'] = "medium" should set the property value
|
||||||
|
Pass e.style['outline'] = "thick" should set the property value
|
||||||
|
Pass e.style['outline'] = "dashed thin" should set the property value
|
||||||
|
Pass e.style['outline'] = "medium rgba(10, 20, 30, 0.4)" should set the property value
|
||||||
|
Pass e.style['outline'] = "3px ridge rgba(10, 20, 30, 0.4)" should set the property value
|
|
@ -0,0 +1,23 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS Backgrounds and Borders Module Level 3: parsing border with valid values</title>
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-backgrounds/#border-shorthands">
|
||||||
|
<meta name="assert" content="border supports the full grammar '<line-width> || <line-style> || <color>'.">
|
||||||
|
<script src="../../../resources/testharness.js"></script>
|
||||||
|
<script src="../../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../../../css/support/parsing-testcommon.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
test_valid_value("border", "1px dotted red");
|
||||||
|
test_valid_value("border", "green double thin", "thin double green");
|
||||||
|
|
||||||
|
test_valid_value("border-top", "thin", ["thin", "thin none"]);
|
||||||
|
test_valid_value("border-right", "double", ["double", "medium double"]);
|
||||||
|
test_valid_value("border-bottom", "green", ["green", "medium none green"]);
|
||||||
|
test_valid_value("border-left", "1px dotted red");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,43 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset="utf-8">
|
||||||
|
<title>CSS UI Level 3: parsing outline with valid values</title>
|
||||||
|
<link rel="author" title="Eric Willigers" href="mailto:ericwilligers@chromium.org">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/css-ui-3/#outline">
|
||||||
|
<link rel="help" href="https://drafts.csswg.org/cssom/#serializing-css-values">
|
||||||
|
<meta name="assert" content="outline supports the full grammar '<outline-color> || <outline> || <outline>'.">
|
||||||
|
<meta name="assert" content="outline serializes in canonical order, with shortest possible serialization.">
|
||||||
|
<script src="../../../resources/testharness.js"></script>
|
||||||
|
<script src="../../../resources/testharnessreport.js"></script>
|
||||||
|
<script src="../../../css/support/parsing-testcommon.js"></script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<script>
|
||||||
|
test_valid_value("outline", "rgba(10, 20, 30, 0.4)");
|
||||||
|
|
||||||
|
test_valid_value("outline", "auto");
|
||||||
|
test_valid_value("outline", "none", ["currentcolor", "none", "medium"]);
|
||||||
|
test_valid_value("outline", "dotted");
|
||||||
|
test_valid_value("outline", "dashed");
|
||||||
|
test_valid_value("outline", "solid");
|
||||||
|
test_valid_value("outline", "double");
|
||||||
|
test_valid_value("outline", "groove");
|
||||||
|
test_valid_value("outline", "ridge");
|
||||||
|
test_valid_value("outline", "inset");
|
||||||
|
test_valid_value("outline", "outset");
|
||||||
|
|
||||||
|
test_valid_value("outline", "0", "0px");
|
||||||
|
test_valid_value("outline", "1px");
|
||||||
|
test_valid_value("outline", "calc(2em + 3ex)");
|
||||||
|
test_valid_value("outline", "thin");
|
||||||
|
test_valid_value("outline", "medium", ["currentcolor", "none", "medium"]);
|
||||||
|
test_valid_value("outline", "thick");
|
||||||
|
|
||||||
|
test_valid_value("outline", "dashed thin");
|
||||||
|
test_valid_value("outline", "medium rgba(10, 20, 30, 0.4)", ["rgba(10, 20, 30, 0.4) medium", "rgba(10, 20, 30, 0.4)"]);
|
||||||
|
|
||||||
|
test_valid_value("outline", "3px ridge rgba(10, 20, 30, 0.4)", "rgba(10, 20, 30, 0.4) ridge 3px");
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
Loading…
Add table
Add a link
Reference in a new issue