1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-27 01:17:35 +00:00

LibWeb: Fix whitespace getting trimmed incorrectly

Whitespace at the end of line should only be trimmed when
'white-space' is set to 'normal', 'nowrap', or 'pre-line'.
This commit is contained in:
Sebastian Zaha 2023-07-16 14:10:47 +02:00 committed by Andreas Kling
parent ce4b09dfd1
commit 92b56ded02
3 changed files with 41 additions and 13 deletions

View file

@ -0,0 +1,9 @@
Viewport <#document> at (0,0) content-size 800x600 children: not-inline
BlockContainer <html> at (0,0) content-size 800x600 [BFC] children: not-inline
BlockContainer <body> at (8,8) content-size 784x17.46875 children: inline
line 0 width: 21.875, height: 17.46875, bottom: 17.46875, baseline: 13.53125
frag 0 from TextNode start: 0, length: 3, rect: [9,8 19.875x17.46875]
" | "
InlineNode <pre>
TextNode <#text>
TextNode <#text>

View file

@ -0,0 +1,7 @@
<style>
pre {
display: inline;
border: 1px solid #000;
}
</style>
<pre> | </pre>

View file

@ -33,27 +33,39 @@ void LineBox::add_fragment(Node const& layout_node, int start, int length, CSSPi
void LineBox::trim_trailing_whitespace() void LineBox::trim_trailing_whitespace()
{ {
while (!m_fragments.is_empty() && m_fragments.last().is_justifiable_whitespace()) { auto should_trim = [](LineBoxFragment* fragment) {
auto fragment = m_fragments.take_last(); auto ws = fragment->layout_node().computed_values().white_space();
m_width -= fragment.width(); return ws == CSS::WhiteSpace::Normal || ws == CSS::WhiteSpace::Nowrap || ws == CSS::WhiteSpace::PreLine;
} };
LineBoxFragment* last_fragment = nullptr;
for (;;) {
if (m_fragments.is_empty()) if (m_fragments.is_empty())
return; return;
// last_fragment cannot be null from here on down, as m_fragments is not empty.
last_fragment = &m_fragments.last();
if (!should_trim(last_fragment))
return;
if (last_fragment->is_justifiable_whitespace()) {
m_width -= last_fragment->width();
m_fragments.remove(m_fragments.size() - 1);
} else {
break;
}
}
auto& last_fragment = m_fragments.last(); auto last_text = last_fragment->text();
auto last_text = last_fragment.text();
if (last_text.is_null()) if (last_text.is_null())
return; return;
while (last_fragment.length()) { while (last_fragment->length()) {
auto last_character = last_text[last_fragment.length() - 1]; auto last_character = last_text[last_fragment->length() - 1];
if (!is_ascii_space(last_character)) if (!is_ascii_space(last_character))
break; break;
int last_character_width = last_fragment.layout_node().font().glyph_width(last_character); int last_character_width = last_fragment->layout_node().font().glyph_width(last_character);
last_fragment.m_length -= 1; last_fragment->m_length -= 1;
last_fragment.set_width(last_fragment.width() - last_character_width); last_fragment->set_width(last_fragment->width() - last_character_width);
m_width -= last_character_width; m_width -= last_character_width;
} }
} }