mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-09-08 10:36:02 +00:00
LibWeb: Convert white-space
CSS property to shorthand
This exposed a few bugs which caused the following tests to behave incorrectly: - `tab-size-text-wrap.html`: This previously relied on a bug where we incorrectly treated `white-space: pre` as allowing text wrapping. The fix here is to implement the text-wrap CSS shorthand property. - `execCommand-preserveWhitespace.html`: We don't correctly serialize shorthand properties. This is covered by an existing FIXME in `CSSStyleProperties::serialized()` - `white-space-shorthand.html`: The last 5 subtests here fail as we don't correctly handle shorthand properties in `CSSStyleProperties::remove_property()`. This is covered by an existing FIXME in said function.
This commit is contained in:
parent
9d06c86fe4
commit
94f5a51820
Notes:
github-actions[bot]
2025-05-29 10:05:43 +00:00
Author: https://github.com/Calme1709
Commit: 94f5a51820
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/4832
Reviewed-by: https://github.com/AtkinsSJ
Reviewed-by: https://github.com/gmta ✅
28 changed files with 568 additions and 308 deletions
|
@ -61,6 +61,38 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
|
|||
if (all_same_keyword && built_in_keyword.has_value())
|
||||
return m_properties.values.first()->to_string(mode);
|
||||
|
||||
auto default_to_string = [&]() {
|
||||
auto all_properties_same_value = true;
|
||||
auto first_property_value = m_properties.values.first();
|
||||
for (auto i = 1u; i < m_properties.values.size(); ++i) {
|
||||
if (m_properties.values[i] != first_property_value) {
|
||||
all_properties_same_value = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (all_properties_same_value)
|
||||
return first_property_value->to_string(mode);
|
||||
|
||||
StringBuilder builder;
|
||||
auto first = true;
|
||||
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)
|
||||
first = false;
|
||||
else
|
||||
builder.append(' ');
|
||||
builder.append(value->to_string(mode));
|
||||
}
|
||||
if (builder.is_empty())
|
||||
return m_properties.values.first()->to_string(mode);
|
||||
|
||||
return MUST(builder.to_string());
|
||||
};
|
||||
|
||||
// Then special cases
|
||||
switch (m_properties.shorthand_property) {
|
||||
case PropertyID::Background: {
|
||||
|
@ -402,36 +434,34 @@ String ShorthandStyleValue::to_string(SerializationMode mode) const
|
|||
|
||||
return builder.to_string_without_validation();
|
||||
}
|
||||
case PropertyID::WhiteSpace: {
|
||||
auto white_space_collapse_property = longhand(PropertyID::WhiteSpaceCollapse);
|
||||
auto text_wrap_mode_property = longhand(PropertyID::TextWrapMode);
|
||||
auto white_space_trim_property = longhand(PropertyID::WhiteSpaceTrim);
|
||||
|
||||
RefPtr<CSSStyleValue const> value;
|
||||
|
||||
if (white_space_trim_property->is_keyword() && white_space_trim_property->as_keyword().keyword() == Keyword::None) {
|
||||
auto white_space_collapse_keyword = white_space_collapse_property->as_keyword().keyword();
|
||||
auto text_wrap_mode_keyword = text_wrap_mode_property->as_keyword().keyword();
|
||||
|
||||
if (white_space_collapse_keyword == Keyword::Collapse && text_wrap_mode_keyword == Keyword::Wrap)
|
||||
return "normal"_string;
|
||||
|
||||
if (white_space_collapse_keyword == Keyword::Preserve && text_wrap_mode_keyword == Keyword::Nowrap)
|
||||
return "pre"_string;
|
||||
|
||||
if (white_space_collapse_keyword == Keyword::Preserve && text_wrap_mode_keyword == Keyword::Wrap)
|
||||
return "pre-wrap"_string;
|
||||
|
||||
if (white_space_collapse_keyword == Keyword::PreserveBreaks && text_wrap_mode_keyword == Keyword::Wrap)
|
||||
return "pre-line"_string;
|
||||
}
|
||||
|
||||
return default_to_string();
|
||||
}
|
||||
default:
|
||||
auto all_properties_same_value = true;
|
||||
auto first_property_value = m_properties.values.first();
|
||||
for (auto i = 1u; i < m_properties.values.size(); ++i) {
|
||||
if (m_properties.values[i] != first_property_value) {
|
||||
all_properties_same_value = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (all_properties_same_value)
|
||||
return first_property_value->to_string(mode);
|
||||
|
||||
StringBuilder builder;
|
||||
auto first = true;
|
||||
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)
|
||||
first = false;
|
||||
else
|
||||
builder.append(' ');
|
||||
builder.append(value->to_string(mode));
|
||||
}
|
||||
if (builder.is_empty())
|
||||
return m_properties.values.first()->to_string(mode);
|
||||
|
||||
return MUST(builder.to_string());
|
||||
return default_to_string();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue