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:
Callum Law 2025-05-22 00:31:24 +12:00 committed by Jelle Raaijmakers
commit 94f5a51820
Notes: github-actions[bot] 2025-05-29 10:05:43 +00:00
28 changed files with 568 additions and 308 deletions

View file

@ -155,7 +155,7 @@ CSSPixels InlineLevelIterator::next_non_whitespace_sequence_width()
auto& next_item = m_lookahead_items.tail();
if (next_item.type == InlineLevelIterator::Item::Type::ForcedBreak)
break;
if (next_item.node->computed_values().white_space() != CSS::WhiteSpace::Nowrap) {
if (next_item.node->computed_values().text_wrap_mode() == CSS::TextWrapMode::Wrap) {
if (next_item.type != InlineLevelIterator::Item::Type::Text)
break;
if (next_item.is_collapsible_whitespace)
@ -640,27 +640,12 @@ Optional<InlineLevelIterator::Item> InlineLevelIterator::next_without_lookahead(
void InlineLevelIterator::enter_text_node(Layout::TextNode const& text_node)
{
bool do_collapse = true;
bool do_wrap_lines = true;
bool do_respect_linebreaks = false;
auto white_space_collapse = text_node.computed_values().white_space_collapse();
auto text_wrap_mode = text_node.computed_values().text_wrap_mode();
if (text_node.computed_values().white_space() == CSS::WhiteSpace::Nowrap) {
do_collapse = true;
do_wrap_lines = false;
do_respect_linebreaks = false;
} else if (text_node.computed_values().white_space() == CSS::WhiteSpace::Pre) {
do_collapse = false;
do_wrap_lines = false;
do_respect_linebreaks = true;
} else if (text_node.computed_values().white_space() == CSS::WhiteSpace::PreLine) {
do_collapse = true;
do_wrap_lines = true;
do_respect_linebreaks = true;
} else if (text_node.computed_values().white_space() == CSS::WhiteSpace::PreWrap) {
do_collapse = false;
do_wrap_lines = true;
do_respect_linebreaks = true;
}
bool do_collapse = white_space_collapse == CSS::WhiteSpaceCollapse::Collapse || white_space_collapse == CSS::WhiteSpaceCollapse::PreserveBreaks;
bool do_wrap_lines = text_wrap_mode == CSS::TextWrapMode::Wrap;
bool do_respect_linebreaks = white_space_collapse == CSS::WhiteSpaceCollapse::Preserve || white_space_collapse == CSS::WhiteSpaceCollapse::PreserveBreaks || white_space_collapse == CSS::WhiteSpaceCollapse::BreakSpaces;
if (text_node.dom_node().is_editable() && !text_node.dom_node().is_uninteresting_whitespace_node())
do_collapse = false;